のどあめ

ググってもなかなか出てこなかった情報を垂れ流すブログ。

OpenCV 3.0.0 alpha で Dense samplingする

さて,OpenCV 3.0.0 alphaがリリースされて結構たちましたね.
研究室のうちのグループでは調子に乗って一足先にグループ内ライブラリにOpenCV 3.0.0-alphaを取り入れましたが,あれがないこれがない,などと色々と困ったことになったりしました.

さて,その中のうちの一つとして「OpenCV3.0.0 alphaからDense Samplingがなくなった」というものがあります.
参考:OpenCV3.0.0-alphaの特徴抽出・マッチングまとめ - whoopsidaisies's diary

これは,Bag-of-featuresの時代は終わったということなのでしょうか・・・

まあ,Dense Samplingぐらいすぐ実装できる,と思っていたのですが,
いざやってみると結構躓いたので記事にしました.

Dense Samplingの実装

OpenCVのcv::FeatureDetectorの子クラスとして,
Dense Samplingを実装しました.

DenseFeatureDetector.h

#pragma once

#include <opencv2/opencv.hpp>
namespace cv {
  class DenseFeatureDetector : public cv::FeatureDetector {
  public:
    struct Param{
      int xStep = 4;
      int yStep = 4;

      float initFeatureScale = 1.0f;
      int scaleLevels = 1;
      float featureScaleMul = 1.2f;

      int imgBoundX = 0;
      int imgBoundY = 0;

      bool varyXyStepWithScale = true;
      bool varyImgBoundWithScale = false;
      Param(){}
    }param;

    DenseFeatureDetector(){}
    DenseFeatureDetector(const Param& p)
      :param(p)
    {
    }

    static cv::AlgorithmInfo& _info();
    virtual cv::AlgorithmInfo* info()const override;

    virtual void detectImpl(cv::InputArray image, std::vector<cv::KeyPoint>& keypoints, cv::InputArray mask = cv::noArray()) const override;

    static cv::Ptr<FeatureDetector> create(const Param& p=Param()){
      return cv::Ptr<FeatureDetector>(new DenseFeatureDetector(p));
    }
  };
}

DenseFeatureDetector.cpp

#include "DenseFeatureDetector.h"

namespace cv{
#define CV_INIT_ALGORITHM(classname, algname, memberinit) \
  static inline ::cv::Algorithm* create##classname##_hidden() \
  { \
    return new classname; \
  } \
  \
  static inline ::cv::Ptr< ::cv::Algorithm> create##classname##_ptr_hidden() \
  { \
    return ::cv::makePtr<classname>(); \
  } \
  \
  static inline ::cv::AlgorithmInfo& classname##_info() \
  { \
    static ::cv::AlgorithmInfo classname##_info_var(algname, create##classname##_hidden); \
    return classname##_info_var; \
  } \
  \
  static ::cv::AlgorithmInfo& classname##_info_auto = classname##_info(); \
  \
  ::cv::AlgorithmInfo* classname::info() const \
  { \
    static volatile bool initialized = false; \
    \
    if( !initialized ) \
    { \
      initialized = true; \
      classname obj; \
      memberinit; \
    } \
    return &classname##_info(); \
  }

  CV_INIT_ALGORITHM(DenseFeatureDetector, "Dense",);

  void DenseFeatureDetector::detectImpl(cv::InputArray image, std::vector<cv::KeyPoint>& keypoints, cv::InputArray mask) const
  {
    cv::Mat maskMat = mask.empty() ? cv::Mat(image.size(), CV_8UC1, cv::Scalar(255)) : mask.getMat();
    cv::Mat imageMat = image.getMat();

    int width = imageMat.cols;
    int height = imageMat.rows;

    int nowBoundX = param.imgBoundX;
    int nowBoundY = param.imgBoundY;

    int nowXStep = param.xStep;
    int nowYStep = param.yStep;

    float nowFeatureSize = param.initFeatureScale;

    for (int s = 0; s < param.scaleLevels; s++){
      for (int y = nowBoundY; y < height; y += nowYStep){
        unsigned char* maskline = maskMat.ptr<unsigned char>(y);

        for (int x = nowBoundX; x < width; x += nowXStep){
          if (maskline[x] > 128){
            cv::KeyPoint kp;
            kp.pt = cv::Point(x, y);
            kp.size = nowFeatureSize;
            kp.response = 100.0f;
            keypoints.push_back(kp);
          }
        }
      }

      if (param.varyImgBoundWithScale){
        nowBoundX *= param.featureScaleMul;
        nowBoundY *= param.featureScaleMul;
      }
      if (param.varyXyStepWithScale){
        nowXStep *= param.featureScaleMul;
        nowYStep *= param.featureScaleMul;
      }
      nowFeatureSize *= param.featureScaleMul;
    }
  }
}

以上です.

使い方としては,

#include "DenseFeatureDetector.h"

int main(){
  cv::Mat img = cv::imread("lena.jpg");

  cv::DenseFeatureDetector::Param p;
  p.scaleLevels = 3;
  p.featureScaleMul = 1.5;
  p.xStep = 20;
  p.yStep = 20;
  cv::Ptr<cv::FeatureDetector> detector = cv::DenseFeatureDetector::create(p);

  std::vector<cv::KeyPoint> keypoints;
  detector->detect(img,keypoints);

  for(auto& k : keypoints){
    std::cout << "Pt : "<< k.pt << " Size :" << k.size << std::endl;
  }

  return 0;
}

出力

Pt : [0, 0] Size :1
Pt : [20, 0] Size :1
Pt : [40, 0] Size :1
Pt : [60, 0] Size :1
(中略)
Pt : [180, 270] Size :2.25
Pt : [225, 270] Size :2.25
Pt : [270, 270] Size :2.25
Pt : [315, 270] Size :2.25
Pt : [360, 270] Size :2.25

こんなかんじです.

cv::Algorithmを継承したクラスは基本的にCV_INIT_ALGORITHMを使う必要があるみたいですね.
(´・ω・`)知らんがな.
これに気づくまでに結構時間がかかりました.

本当はcv::FeatureDetector::create("Dense")みたいなことがしたいのですが,これはOpenCVを再コンパイルする必要があると思うので,今回はとりあえず使えればOKというスタンスで実装しました.

何にせよ,これを使えばOpenCV 3.0 alphaでもDense Samplingが出来るようになりました!めでたしめでたし.

なお,この実装はOpenCVのgitリポジトリがHEADだと動かないみたいなので,
3.0.0 alphaにチェックアウトしてから使ってください.

今回のまとめ

  • OpenCV 3.0 alpha をメインプログラムに使うのはやめよう
  • Dense Samplingしたい人はOpenCV 2.4.9を使おう

今回参考にしたWebページ


次回は,FisherVectorか,Sparse Codingについて記事を書きたいと思います.

cv::SVMのsampleIdxの使い方

先日OpenCVのcv::SVMを使っていた時に、引数のsampleIdx(とvarIdx)の使い方がリファレンスに載っていなかったので、メモついでに記事にしました。

SVMとは

(略)

cv::SVMコンストラクタもといtrainの引数について

リファレンスによると、

cv::SVM::train(
  const cv::Mat& trainData, 
  const cv::Mat& responses,
  const cv::Mat& varIdx=cv::Mat(),
  const cv::Mat& sampleIdx=cv::Mat(), 
  cv::SVMParams params=cv::SVMParams() 
)
  • trainData:学習に用いるサンプルの特徴量。n個のdim次元の特徴量を格納したn x dim のcv::Matで表す。
  • responses:学習に用いるサンプルのラベル。n個の-1または1の値を格納した1 x dim のcv::Matで表す。
  • varIdx:学習に用いる特徴量のindex。trainDataの特徴量の一部の次元のみを利用して学習したいときに用いる。
  • sampleIdx:学習に用いるサンプルのindex。trainDataの一部の行のみを利用して学習したいときに用いる。
  • params:svmのパラメータ。詳細はリファレンス参照。

という感じです。

利用例

#include <opencv2/opencv.hpp>

int main(){
    cv::Mat trainData = (cv::Mat_<float>(4,2) << 1,1, 2,2, -1,-1, -2,-1);
    cv::Mat responses = (cv::Mat_<float>(4,1) << 1,1, -1,-1);

    cv::Mat sampleIdx = (cv::Mat_<int>(2,1) << 0,2);
	
    cv::SVM svm;
    svm.train(trainData,responses,cv::Mat(),sampleIdx);

    std::cout << svm.predict((cv::Mat_<float>(1,2) << 3,2)) << std::endl;
}

こんな感じです。
#sampleIdxをn x 1のcv::Matを使って0,1で表現すると思って詰んだのは秘密・・・

MinGWのg++でコンパイルしたstd::coutを含むプログラムが強制終了する問題について

MinGW + gVim + QuickRunでテストプログラムを動かす環境を整えてみたら、
何故かMinGWコンパイルした一部のプログラムが強制終了することに気づきました。

#include <iostream>
int main(){
   std::cout << "a" << std::endl;
   return 0;
}

これが強制終了します(コンパイルは通る)。
他のPCのMinGWだとうまくいくのに・・・

今回は、この問題を解決する方法を見つけたので紹介します。


解決法1 : 静的ライブラリでコンパイル

>g++ test.cpp -static-libstd
>a.exe

これで動きました。

これは、つまりdllがおかしいということですね。

どうやら、STL関連のDLLはlibstdc++-6.dllとlibgcc_s_sjlj-1.dllの2つのようです。

ちゃんとパスが通っているか、再インストールしてみたらどうか、
色々と試してみましたが、問題は解決しませんでした。

しかし、ふと「libstdc++-6.dll」でファイル検索してみたところ、
なんとMinGWとは別のlibstdc++-6.dllが存在することを発見しました!!


解決法2 : dllの競合をなくす

どうやら、過去に入れた「Octave 3.6.4 for Windows MinGW」があるのに気が付かずに、
新たに最新版のMinGWを入れたのが問題だったようです。
Octave同封のlibstdc++-6.dllの方が先にパスを通していたので、
実行時にOctave側のdllを読みに行って落ちていたようです。

試しに、Octaveのパスを消してみると無事プログラムを動かすことが出来ました。
そして、今は特にOctaveを使う用事もないので、アンインストールすることで事なきを得ました。
(何の解決にもなってない)

Octaveを使う人は、VisualStudio版を使うか、MinGWのバージョンを合わせるか、
どちらかのパスを通さないかすればいいのではないでしょうか。


今回は結構うっかりな問題でしたが、
dllのバージョンが違う場合は強制終了せずに警告を出すぐらいしてくれても・・・

VisualStudio 2012のデバッグ中にOpenCVのcv::Matの中身を確認する方法

私はVisualStudioの拡張機能であるImageWatchを使っています。
ImageWatchはOpenCVで読み込んだ画像などをデバッグ中に可視化する事ができます。
ImageWatchはとても便利なのですが、大きなCV_64Fの二次元のcv::Mat型などの中身を見るのには不便です。

以下のようにコマンドウィンドウを用いる方法もありますが、

>? ((double*)mat.data)[mat.rows*4+2]

ある要素(上の場合は(4,2))を見たいだけならいいのですが、
内容をずらっと見たい時に不便ですし、何より入力するのが面倒です。

今回はImageWatchのnatvisを改造して、この問題に対処したいと思います。

natvisとは

公式ページによると、

  • VisualStudioデバッガの表示をカスタマイズするフレームワーク
  • 昔はautoexp.datがやっていた。
  • xml形式でかけるのでわかりやすい

ということみたいです。
ImageWatchを入れると、cv::Matのデバッグ表示が変わるのはこのためです。
今回はImageWatchのnatvisを改造してcv::Matの中身を一緒に表示させるようにします。

natvisの改造

ImageWatchのOpenCV関連のnatvisファイルはデフォルトで、

C:\Users\username\AppData\Local\Microsoft\VisualStudio\11.0\Extensions\謎文字列?\ImageWatchOpenCV.natvis

に保存されています。

この中の以下のように改造します。
※念のためバックアップは取ってください。

・・・
  <Type Name="cv::Mat">
    <AlternativeType Name="cv::Mat_&lt;*&gt;"/>
    <DisplayString Condition="(flags&amp;7)==0">{{UINT8, {((flags&amp;0xfff)&gt;&gt;3)+1} x {cols} x {rows}}}</DisplayString>
    <DisplayString Condition="(flags&amp;7)==1">{{INT8, {((flags&amp;0xfff)&gt;&gt;3)+1} x {cols} x {rows}}}</DisplayString>
    <DisplayString Condition="(flags&amp;7)==2">{{UINT16, {((flags&amp;0xfff)&gt;&gt;3)+1} x {cols} x {rows}}}</DisplayString>
    <DisplayString Condition="(flags&amp;7)==3">{{INT16, {((flags&amp;0xfff)&gt;&gt;3)+1} x {cols} x {rows}}}</DisplayString>
    <DisplayString Condition="(flags&amp;7)==4">{{INT32, {((flags&amp;0xfff)&gt;&gt;3)+1} x {cols} x {rows}}}</DisplayString>
    <DisplayString Condition="(flags&amp;7)==5">{{FLOAT32, {((flags&amp;0xfff)&gt;&gt;3)+1} x {cols} x {rows}}}</DisplayString>
    <DisplayString Condition="(flags&amp;7)==6">{{FLOAT64, {((flags&amp;0xfff)&gt;&gt;3)+1} x {cols} x {rows}}}</DisplayString>
    <DisplayString Condition="(flags&amp;7)==7">{{USER, {((flags&amp;0xfff)&gt;&gt;3)+1} x {cols} x {rows}}}</DisplayString>
    <Expand>
      <Synthetic Name="[type]" Condition="(flags&amp;7)==0">
        <DisplayString>UINT8</DisplayString>
      </Synthetic>
      <Synthetic Name="[type]" Condition="(flags&amp;7)==1">
        <DisplayString>INT8</DisplayString>
      </Synthetic>
      <Synthetic Name="[type]" Condition="(flags&amp;7)==2">
        <DisplayString>UINT16</DisplayString>
      </Synthetic>
      <Synthetic Name="[type]" Condition="(flags&amp;7)==3">
        <DisplayString>INT16</DisplayString>
      </Synthetic>
      <Synthetic Name="[type]" Condition="(flags&amp;7)==4">
        <DisplayString>INT32</DisplayString>
      </Synthetic>
      <Synthetic Name="[type]" Condition="(flags&amp;7)==5">
        <DisplayString>FLOAT32</DisplayString>
      </Synthetic>
      <Synthetic Name="[type]" Condition="(flags&amp;7)==6">
        <DisplayString>FLOAT64</DisplayString>
      </Synthetic>
      <Item Name="[channels]">((flags&amp;0xfff)&gt;&gt;3)+1</Item>
      <Item Name="[width]">cols</Item>
      <Item Name="[height]">rows</Item>
		<Synthetic Name="[detail]" Condition="dims == 2 &amp;&amp; (flags &amp; 7) == 0 &amp;&amp; (flags &amp; 16384) == 16384"><!-- 8U -->
			<Expand>
				<Synthetic Name="row[0]" Condition="rows &gt; 0">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((unsigned char*)data)[$i+0*cols])</ValueNode></IndexListItems></Expand></Synthetic>
				<Synthetic Name="row[1]" Condition="rows &gt; 1">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((unsigned char*)data)[$i+1*cols])</ValueNode></IndexListItems></Expand></Synthetic>
				<Synthetic Name="row[2]" Condition="rows &gt; 2">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((unsigned char*)data)[$i+2*cols])</ValueNode></IndexListItems></Expand></Synthetic>
				<Synthetic Name="row[3]" Condition="rows &gt; 3 &amp;&amp; rows &lt; 7">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((unsigned char*)data)[$i+3*cols])</ValueNode></IndexListItems></Expand></Synthetic>
				<Synthetic Name="row[4]" Condition="rows &gt; 4 &amp;&amp; rows &lt; 7">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((unsigned char*)data)[$i+4*cols])</ValueNode></IndexListItems></Expand></Synthetic>
				<Synthetic Name="row[5]" Condition="rows &gt; 5 &amp;&amp; rows &lt; 7">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((unsigned char*)data)[$i+5*cols])</ValueNode></IndexListItems></Expand></Synthetic>
				<Synthetic Name="..." Condition="rows &gt; 6"><DisplayString> </DisplayString></Synthetic>  
				<Synthetic Name="row[-3]" Condition="rows &gt; 6">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((unsigned char*)data)[$i+(rows-3)*cols])</ValueNode></IndexListItems></Expand></Synthetic>
				<Synthetic Name="row[-2]" Condition="rows &gt; 6">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((unsigned char*)data)[$i+(rows-2)*cols])</ValueNode></IndexListItems></Expand></Synthetic>
				<Synthetic Name="row[-1]" Condition="rows &gt; 6">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((unsigned char*)data)[$i+(rows-1)*cols])</ValueNode></IndexListItems></Expand></Synthetic>
			</Expand>
		</Synthetic>
		<Synthetic Name="[detail]" Condition="dims == 2 &amp;&amp; (flags &amp; 7) == 1 &amp;&amp; (flags &amp; 16384) == 16384"><!-- 8S -->
			<Expand>
				<Synthetic Name="row[0]" Condition="rows &gt; 0">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((char*)data)[$i+0*cols])</ValueNode></IndexListItems></Expand></Synthetic>
				<Synthetic Name="row[1]" Condition="rows &gt; 1">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((char*)data)[$i+1*cols])</ValueNode></IndexListItems></Expand></Synthetic>
				<Synthetic Name="row[2]" Condition="rows &gt; 2">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((char*)data)[$i+2*cols])</ValueNode></IndexListItems></Expand></Synthetic>
				<Synthetic Name="row[3]" Condition="rows &gt; 3 &amp;&amp; rows &lt; 7">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((char*)data)[$i+3*cols])</ValueNode></IndexListItems></Expand></Synthetic>
				<Synthetic Name="row[4]" Condition="rows &gt; 4 &amp;&amp; rows &lt; 7">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((char*)data)[$i+4*cols])</ValueNode></IndexListItems></Expand></Synthetic>
				<Synthetic Name="row[5]" Condition="rows &gt; 5 &amp;&amp; rows &lt; 7">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((char*)data)[$i+5*cols])</ValueNode></IndexListItems></Expand></Synthetic>
				<Synthetic Name="..." Condition="rows &gt; 6"><DisplayString> </DisplayString></Synthetic>  
				<Synthetic Name="row[-3]" Condition="rows &gt; 6">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((char*)data)[$i+(rows-3)*cols])</ValueNode></IndexListItems></Expand></Synthetic>
				<Synthetic Name="row[-2]" Condition="rows &gt; 6">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((char*)data)[$i+(rows-2)*cols])</ValueNode></IndexListItems></Expand></Synthetic>
				<Synthetic Name="row[-1]" Condition="rows &gt; 6">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((char*)data)[$i+(rows-1)*cols])</ValueNode></IndexListItems></Expand></Synthetic>
			</Expand>
		</Synthetic>
		<Synthetic Name="[detail]" Condition="dims == 2 &amp;&amp; (flags &amp; 7) == 2 &amp;&amp; (flags &amp; 16384) == 16384"><!-- 16U -->
			<Expand>
				<Synthetic Name="row[0]" Condition="rows &gt; 0">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((unsigned short*)data)[$i+0*cols])</ValueNode></IndexListItems></Expand></Synthetic>
				<Synthetic Name="row[1]" Condition="rows &gt; 1">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((unsigned short*)data)[$i+1*cols])</ValueNode></IndexListItems></Expand></Synthetic>
				<Synthetic Name="row[2]" Condition="rows &gt; 2">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((unsigned short*)data)[$i+2*cols])</ValueNode></IndexListItems></Expand></Synthetic>
				<Synthetic Name="row[3]" Condition="rows &gt; 3 &amp;&amp; rows &lt; 7">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((unsigned short*)data)[$i+3*cols])</ValueNode></IndexListItems></Expand></Synthetic>
				<Synthetic Name="row[4]" Condition="rows &gt; 4 &amp;&amp; rows &lt; 7">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((unsigned short*)data)[$i+4*cols])</ValueNode></IndexListItems></Expand></Synthetic>
				<Synthetic Name="row[5]" Condition="rows &gt; 5 &amp;&amp; rows &lt; 7">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((unsigned short*)data)[$i+5*cols])</ValueNode></IndexListItems></Expand></Synthetic>
				<Synthetic Name="..." Condition="rows &gt; 6"><DisplayString> </DisplayString></Synthetic>  
				<Synthetic Name="row[-3]" Condition="rows &gt; 6">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((unsigned short*)data)[$i+(rows-3)*cols])</ValueNode></IndexListItems></Expand></Synthetic>
				<Synthetic Name="row[-2]" Condition="rows &gt; 6">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((unsigned short*)data)[$i+(rows-2)*cols])</ValueNode></IndexListItems></Expand></Synthetic>
				<Synthetic Name="row[-1]" Condition="rows &gt; 6">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((unsigned short*)data)[$i+(rows-1)*cols])</ValueNode></IndexListItems></Expand></Synthetic>
			</Expand>
		</Synthetic>
		<Synthetic Name="[detail]" Condition="dims == 2 &amp;&amp; (flags &amp; 7) == 3 &amp;&amp; (flags &amp; 16384) == 16384"><!-- 16S -->
			<Expand>
				<Synthetic Name="row[0]" Condition="rows &gt; 0">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((short*)data)[$i+0*cols])</ValueNode></IndexListItems></Expand></Synthetic>
				<Synthetic Name="row[1]" Condition="rows &gt; 1">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((short*)data)[$i+1*cols])</ValueNode></IndexListItems></Expand></Synthetic>
				<Synthetic Name="row[2]" Condition="rows &gt; 2">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((short*)data)[$i+2*cols])</ValueNode></IndexListItems></Expand></Synthetic>
				<Synthetic Name="row[3]" Condition="rows &gt; 3 &amp;&amp; rows &lt; 7">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((short*)data)[$i+3*cols])</ValueNode></IndexListItems></Expand></Synthetic>
				<Synthetic Name="row[4]" Condition="rows &gt; 4 &amp;&amp; rows &lt; 7">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((short*)data)[$i+4*cols])</ValueNode></IndexListItems></Expand></Synthetic>
				<Synthetic Name="row[5]" Condition="rows &gt; 5 &amp;&amp; rows &lt; 7">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((short*)data)[$i+5*cols])</ValueNode></IndexListItems></Expand></Synthetic>
				<Synthetic Name="..." Condition="rows &gt; 6"><DisplayString> </DisplayString></Synthetic>  
				<Synthetic Name="row[-3]" Condition="rows &gt; 6">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((short*)data)[$i+(rows-3)*cols])</ValueNode></IndexListItems></Expand></Synthetic>
				<Synthetic Name="row[-2]" Condition="rows &gt; 6">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((short*)data)[$i+(rows-2)*cols])</ValueNode></IndexListItems></Expand></Synthetic>
				<Synthetic Name="row[-1]" Condition="rows &gt; 6">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((short*)data)[$i+(rows-1)*cols])</ValueNode></IndexListItems></Expand></Synthetic>
			</Expand>
		</Synthetic>
		<Synthetic Name="[detail]" Condition="dims == 2 &amp;&amp; (flags &amp; 7) == 4 &amp;&amp; (flags &amp; 16384) == 16384"><!-- 32S -->
			<Expand>
				<Synthetic Name="row[0]" Condition="rows &gt; 0">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((int*)data)[$i+0*cols])</ValueNode></IndexListItems></Expand></Synthetic>
				<Synthetic Name="row[1]" Condition="rows &gt; 1">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((int*)data)[$i+1*cols])</ValueNode></IndexListItems></Expand></Synthetic>
				<Synthetic Name="row[2]" Condition="rows &gt; 2">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((int*)data)[$i+2*cols])</ValueNode></IndexListItems></Expand></Synthetic>
				<Synthetic Name="row[3]" Condition="rows &gt; 3 &amp;&amp; rows &lt; 7">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((int*)data)[$i+3*cols])</ValueNode></IndexListItems></Expand></Synthetic>
				<Synthetic Name="row[4]" Condition="rows &gt; 4 &amp;&amp; rows &lt; 7">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((int*)data)[$i+4*cols])</ValueNode></IndexListItems></Expand></Synthetic>
				<Synthetic Name="row[5]" Condition="rows &gt; 5 &amp;&amp; rows &lt; 7">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((int*)data)[$i+5*cols])</ValueNode></IndexListItems></Expand></Synthetic>
				<Synthetic Name="..." Condition="rows &gt; 6"><DisplayString> </DisplayString></Synthetic>  
				<Synthetic Name="row[-3]" Condition="rows &gt; 6">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((int*)data)[$i+(rows-3)*cols])</ValueNode></IndexListItems></Expand></Synthetic>
				<Synthetic Name="row[-2]" Condition="rows &gt; 6">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((int*)data)[$i+(rows-2)*cols])</ValueNode></IndexListItems></Expand></Synthetic>
				<Synthetic Name="row[-1]" Condition="rows &gt; 6">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((int*)data)[$i+(rows-1)*cols])</ValueNode></IndexListItems></Expand></Synthetic>
			</Expand>
		</Synthetic>
		<Synthetic Name="[detail]" Condition="dims == 2 &amp;&amp; (flags &amp; 7) == 5 &amp;&amp; (flags &amp; 16384) == 16384"><!-- 32F -->
			<Expand>
				<Synthetic Name="row[0]" Condition="rows &gt; 0">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((float*)data)[$i+0*cols])</ValueNode></IndexListItems></Expand></Synthetic>
				<Synthetic Name="row[1]" Condition="rows &gt; 1">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((float*)data)[$i+1*cols])</ValueNode></IndexListItems></Expand></Synthetic>
				<Synthetic Name="row[2]" Condition="rows &gt; 2">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((float*)data)[$i+2*cols])</ValueNode></IndexListItems></Expand></Synthetic>
				<Synthetic Name="row[3]" Condition="rows &gt; 3 &amp;&amp; rows &lt; 7">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((float*)data)[$i+3*cols])</ValueNode></IndexListItems></Expand></Synthetic>
				<Synthetic Name="row[4]" Condition="rows &gt; 4 &amp;&amp; rows &lt; 7">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((float*)data)[$i+4*cols])</ValueNode></IndexListItems></Expand></Synthetic>
				<Synthetic Name="row[5]" Condition="rows &gt; 5 &amp;&amp; rows &lt; 7">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((float*)data)[$i+5*cols])</ValueNode></IndexListItems></Expand></Synthetic>
				<Synthetic Name="..." Condition="rows &gt; 6"><DisplayString> </DisplayString></Synthetic>  
				<Synthetic Name="row[-3]" Condition="rows &gt; 6">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((float*)data)[$i+(rows-3)*cols])</ValueNode></IndexListItems></Expand></Synthetic>
				<Synthetic Name="row[-2]" Condition="rows &gt; 6">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((float*)data)[$i+(rows-2)*cols])</ValueNode></IndexListItems></Expand></Synthetic>
				<Synthetic Name="row[-1]" Condition="rows &gt; 6">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((float*)data)[$i+(rows-1)*cols])</ValueNode></IndexListItems></Expand></Synthetic>
			</Expand>
		</Synthetic>
		<Synthetic Name="[detail]" Condition="dims == 2 &amp;&amp; (flags &amp; 7) == 6 &amp;&amp; (flags &amp; 16384) == 16384"><!-- 64F -->
			<Expand>
				<Synthetic Name="row[0]" Condition="rows &gt; 0">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((double*)data)[$i+0*cols])</ValueNode></IndexListItems></Expand></Synthetic>
				<Synthetic Name="row[1]" Condition="rows &gt; 1">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((double*)data)[$i+1*cols])</ValueNode></IndexListItems></Expand></Synthetic>
				<Synthetic Name="row[2]" Condition="rows &gt; 2">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((double*)data)[$i+2*cols])</ValueNode></IndexListItems></Expand></Synthetic>
				<Synthetic Name="row[3]" Condition="rows &gt; 3 &amp;&amp; rows &lt; 7">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((double*)data)[$i+3*cols])</ValueNode></IndexListItems></Expand></Synthetic>
				<Synthetic Name="row[4]" Condition="rows &gt; 4 &amp;&amp; rows &lt; 7">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((double*)data)[$i+4*cols])</ValueNode></IndexListItems></Expand></Synthetic>
				<Synthetic Name="row[5]" Condition="rows &gt; 5 &amp;&amp; rows &lt; 7">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((double*)data)[$i+5*cols])</ValueNode></IndexListItems></Expand></Synthetic>
				<Synthetic Name="..." Condition="rows &gt; 6"><DisplayString> </DisplayString></Synthetic>  
				<Synthetic Name="row[-3]" Condition="rows &gt; 6">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((double*)data)[$i+(rows-3)*cols])</ValueNode></IndexListItems></Expand></Synthetic>
				<Synthetic Name="row[-2]" Condition="rows &gt; 6">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((double*)data)[$i+(rows-2)*cols])</ValueNode></IndexListItems></Expand></Synthetic>
				<Synthetic Name="row[-1]" Condition="rows &gt; 6">
					<Expand><IndexListItems><Size>cols</Size><ValueNode>(&amp;((double*)data)[$i+(rows-1)*cols])</ValueNode></IndexListItems></Expand></Synthetic>
			</Expand>
		</Synthetic>
      <Item Name="[stride]">step.p[0]</Item>
      <Item Name="[continous]">(flags &amp; 16384) == 16384</Item>
      <Item Name="[submatrix]">(flags &amp; 32678) == 32678</Item>
      <Item Name="[refcount]">refcount</Item>
	  <Item Name="[data]">data</Item>
    </Expand>
  </Type>
・・・

natvisファイルではループ等は使えないため、ゴリゴリ書いています。
今回はcv::Matの中身を6行(上3行、下3行)を見るためのnatvisを(ゴリゴリ)書きました。
他にも色々と可視化したほうがいいような気もしますが、
私個人としてはcv::Matさえ確認できればそれで良いのでこのままです。

必要なら自分で足してください。


これを適用すると、こんな感じになります。
f:id:ykicisk:20131106140258p:plain

大きな行列の中身を見るときに便利になりました!
めでたしめでたし。

Ubuntu 12.04(64bit)にjperlを導入する方法

ちょっと前にjperlなるものを使わざるを得ない機会がありました。
その時に導入に一晩くらいかかってしまったので、その詳細を書いておきます。

そもそもjperlとは何なのか・・・

  • 昔々perlが日本語がうまく扱えないときに、その問題にある程度対処するために作られた
  • 今はencodingプログラマなるものを使えば問題ない
  • Perl 5.5までしか対応していない
  • 現場ではまだまだ現役のところも少なくない

つまり、負の遺産というわけですね・・・

Ubuntu 12.04(64bit)へのjperlの導入

まずは、こちらからperl5.005_04.tar.gzとjperl5.005_04-20040401.pat.gzをダウンロードして、
Webページの指示にしたがってPerlにJperlのパッチを当てる。

$ tar zxvf perl5.005_04.tar.gz
$ gzip -d jperl5.005_04-20040401.pat.gz
$ cd perl5.005_04
$ patch -p1 < ../jperl5.005_04-20040401.pat

次に、既存のperlとは別にperl5.005_04(jperl)をインストールする。

$ sh Configure -Dprefix=/usr/local/perl5.005_04 -Dusethreads -de

それから、

$ make

とするのですが、この段階でいくつかエラーが出るかもしれません(私はでました)。

<command-line>なんとかというエラー

makedependent.SHを編集すればOK

・・・
 '/^#.*<stdin>/d' \
 '/^#.*<builtin>/d' \
 '/^#.*<built-in>/d' \
 '/^#.*<command line>/d' \
 '/^#.*<command-line>/d' \  #この行を追加
 '/^#.*"-"/d' \
 's#\.[0-9][0-9]*\.c#'"$file.c#" \
・・・

math.hがリンクされていないみたいなエラー

sh Configureからやり直し。
■64bit

$ sh Configure -Dprefix=/usr/local/perl5.005_04 -Dusethreads -Dplibpth=/usr/lib/x86_64-linux-gnu -de

■32bit(未確認)

$ sh Configure -Dprefix=/usr/local/perl5.005_04 -Dusethreads -Dplibpth=/usr/lib/i386-linux-gnu -de

さらに、asm/page.hがないとか言われたらシンボリックリンクで対処します。

$ mkdir /usr/include/asm
$ sudo ln -s /usr/src/linux-headers-3.5.0-31/arch/x86/include/asm/page.h /usr/include/asm/page.h

linux-headersのバージョンは違うかもしれません。

そこから、

$ make test
$ sudo make install

して、最後にシンボリックリンクをつくれば完了!

$ sudo ln -s /usr/local/bin/perl5.005_04/bin/perl /usr/local/bin/jperl

実行中に rr_fopen error で /usr/tmp/...のファイルが開けないと言われたら
/usr/tmpディレクトリがないのが原因かもしれません。
その場合は、mkdirで作ってパーミッションを設定すればOKです。


以上です!
これでUbuntuでもjperlが使えます!!
たぶん!

今回の感想

  • jperlは一生使いません。
  • Redhat系は優秀

挨拶

私がプログラミング等でつまずいたところをメモするブログです。

同じ問題で苦しんでいる人の助けになれば幸いです・・・が、私自身はいろいろと力不足なので突っ込んだ質問などには答えられないかもしれません。

動けばそれで良いのです。

 

もし、誤り等あればコメントしていただければ幸いです。

それでは、よろしくお願いいたします。