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とは
公式ページによると、
ということみたいです。
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_<*>"/> <DisplayString Condition="(flags&7)==0">{{UINT8, {((flags&0xfff)>>3)+1} x {cols} x {rows}}}</DisplayString> <DisplayString Condition="(flags&7)==1">{{INT8, {((flags&0xfff)>>3)+1} x {cols} x {rows}}}</DisplayString> <DisplayString Condition="(flags&7)==2">{{UINT16, {((flags&0xfff)>>3)+1} x {cols} x {rows}}}</DisplayString> <DisplayString Condition="(flags&7)==3">{{INT16, {((flags&0xfff)>>3)+1} x {cols} x {rows}}}</DisplayString> <DisplayString Condition="(flags&7)==4">{{INT32, {((flags&0xfff)>>3)+1} x {cols} x {rows}}}</DisplayString> <DisplayString Condition="(flags&7)==5">{{FLOAT32, {((flags&0xfff)>>3)+1} x {cols} x {rows}}}</DisplayString> <DisplayString Condition="(flags&7)==6">{{FLOAT64, {((flags&0xfff)>>3)+1} x {cols} x {rows}}}</DisplayString> <DisplayString Condition="(flags&7)==7">{{USER, {((flags&0xfff)>>3)+1} x {cols} x {rows}}}</DisplayString> <Expand> <Synthetic Name="[type]" Condition="(flags&7)==0"> <DisplayString>UINT8</DisplayString> </Synthetic> <Synthetic Name="[type]" Condition="(flags&7)==1"> <DisplayString>INT8</DisplayString> </Synthetic> <Synthetic Name="[type]" Condition="(flags&7)==2"> <DisplayString>UINT16</DisplayString> </Synthetic> <Synthetic Name="[type]" Condition="(flags&7)==3"> <DisplayString>INT16</DisplayString> </Synthetic> <Synthetic Name="[type]" Condition="(flags&7)==4"> <DisplayString>INT32</DisplayString> </Synthetic> <Synthetic Name="[type]" Condition="(flags&7)==5"> <DisplayString>FLOAT32</DisplayString> </Synthetic> <Synthetic Name="[type]" Condition="(flags&7)==6"> <DisplayString>FLOAT64</DisplayString> </Synthetic> <Item Name="[channels]">((flags&0xfff)>>3)+1</Item> <Item Name="[width]">cols</Item> <Item Name="[height]">rows</Item> <Synthetic Name="[detail]" Condition="dims == 2 && (flags & 7) == 0 && (flags & 16384) == 16384"><!-- 8U --> <Expand> <Synthetic Name="row[0]" Condition="rows > 0"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((unsigned char*)data)[$i+0*cols])</ValueNode></IndexListItems></Expand></Synthetic> <Synthetic Name="row[1]" Condition="rows > 1"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((unsigned char*)data)[$i+1*cols])</ValueNode></IndexListItems></Expand></Synthetic> <Synthetic Name="row[2]" Condition="rows > 2"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((unsigned char*)data)[$i+2*cols])</ValueNode></IndexListItems></Expand></Synthetic> <Synthetic Name="row[3]" Condition="rows > 3 && rows < 7"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((unsigned char*)data)[$i+3*cols])</ValueNode></IndexListItems></Expand></Synthetic> <Synthetic Name="row[4]" Condition="rows > 4 && rows < 7"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((unsigned char*)data)[$i+4*cols])</ValueNode></IndexListItems></Expand></Synthetic> <Synthetic Name="row[5]" Condition="rows > 5 && rows < 7"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((unsigned char*)data)[$i+5*cols])</ValueNode></IndexListItems></Expand></Synthetic> <Synthetic Name="..." Condition="rows > 6"><DisplayString> </DisplayString></Synthetic> <Synthetic Name="row[-3]" Condition="rows > 6"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((unsigned char*)data)[$i+(rows-3)*cols])</ValueNode></IndexListItems></Expand></Synthetic> <Synthetic Name="row[-2]" Condition="rows > 6"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((unsigned char*)data)[$i+(rows-2)*cols])</ValueNode></IndexListItems></Expand></Synthetic> <Synthetic Name="row[-1]" Condition="rows > 6"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((unsigned char*)data)[$i+(rows-1)*cols])</ValueNode></IndexListItems></Expand></Synthetic> </Expand> </Synthetic> <Synthetic Name="[detail]" Condition="dims == 2 && (flags & 7) == 1 && (flags & 16384) == 16384"><!-- 8S --> <Expand> <Synthetic Name="row[0]" Condition="rows > 0"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((char*)data)[$i+0*cols])</ValueNode></IndexListItems></Expand></Synthetic> <Synthetic Name="row[1]" Condition="rows > 1"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((char*)data)[$i+1*cols])</ValueNode></IndexListItems></Expand></Synthetic> <Synthetic Name="row[2]" Condition="rows > 2"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((char*)data)[$i+2*cols])</ValueNode></IndexListItems></Expand></Synthetic> <Synthetic Name="row[3]" Condition="rows > 3 && rows < 7"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((char*)data)[$i+3*cols])</ValueNode></IndexListItems></Expand></Synthetic> <Synthetic Name="row[4]" Condition="rows > 4 && rows < 7"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((char*)data)[$i+4*cols])</ValueNode></IndexListItems></Expand></Synthetic> <Synthetic Name="row[5]" Condition="rows > 5 && rows < 7"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((char*)data)[$i+5*cols])</ValueNode></IndexListItems></Expand></Synthetic> <Synthetic Name="..." Condition="rows > 6"><DisplayString> </DisplayString></Synthetic> <Synthetic Name="row[-3]" Condition="rows > 6"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((char*)data)[$i+(rows-3)*cols])</ValueNode></IndexListItems></Expand></Synthetic> <Synthetic Name="row[-2]" Condition="rows > 6"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((char*)data)[$i+(rows-2)*cols])</ValueNode></IndexListItems></Expand></Synthetic> <Synthetic Name="row[-1]" Condition="rows > 6"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((char*)data)[$i+(rows-1)*cols])</ValueNode></IndexListItems></Expand></Synthetic> </Expand> </Synthetic> <Synthetic Name="[detail]" Condition="dims == 2 && (flags & 7) == 2 && (flags & 16384) == 16384"><!-- 16U --> <Expand> <Synthetic Name="row[0]" Condition="rows > 0"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((unsigned short*)data)[$i+0*cols])</ValueNode></IndexListItems></Expand></Synthetic> <Synthetic Name="row[1]" Condition="rows > 1"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((unsigned short*)data)[$i+1*cols])</ValueNode></IndexListItems></Expand></Synthetic> <Synthetic Name="row[2]" Condition="rows > 2"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((unsigned short*)data)[$i+2*cols])</ValueNode></IndexListItems></Expand></Synthetic> <Synthetic Name="row[3]" Condition="rows > 3 && rows < 7"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((unsigned short*)data)[$i+3*cols])</ValueNode></IndexListItems></Expand></Synthetic> <Synthetic Name="row[4]" Condition="rows > 4 && rows < 7"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((unsigned short*)data)[$i+4*cols])</ValueNode></IndexListItems></Expand></Synthetic> <Synthetic Name="row[5]" Condition="rows > 5 && rows < 7"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((unsigned short*)data)[$i+5*cols])</ValueNode></IndexListItems></Expand></Synthetic> <Synthetic Name="..." Condition="rows > 6"><DisplayString> </DisplayString></Synthetic> <Synthetic Name="row[-3]" Condition="rows > 6"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((unsigned short*)data)[$i+(rows-3)*cols])</ValueNode></IndexListItems></Expand></Synthetic> <Synthetic Name="row[-2]" Condition="rows > 6"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((unsigned short*)data)[$i+(rows-2)*cols])</ValueNode></IndexListItems></Expand></Synthetic> <Synthetic Name="row[-1]" Condition="rows > 6"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((unsigned short*)data)[$i+(rows-1)*cols])</ValueNode></IndexListItems></Expand></Synthetic> </Expand> </Synthetic> <Synthetic Name="[detail]" Condition="dims == 2 && (flags & 7) == 3 && (flags & 16384) == 16384"><!-- 16S --> <Expand> <Synthetic Name="row[0]" Condition="rows > 0"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((short*)data)[$i+0*cols])</ValueNode></IndexListItems></Expand></Synthetic> <Synthetic Name="row[1]" Condition="rows > 1"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((short*)data)[$i+1*cols])</ValueNode></IndexListItems></Expand></Synthetic> <Synthetic Name="row[2]" Condition="rows > 2"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((short*)data)[$i+2*cols])</ValueNode></IndexListItems></Expand></Synthetic> <Synthetic Name="row[3]" Condition="rows > 3 && rows < 7"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((short*)data)[$i+3*cols])</ValueNode></IndexListItems></Expand></Synthetic> <Synthetic Name="row[4]" Condition="rows > 4 && rows < 7"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((short*)data)[$i+4*cols])</ValueNode></IndexListItems></Expand></Synthetic> <Synthetic Name="row[5]" Condition="rows > 5 && rows < 7"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((short*)data)[$i+5*cols])</ValueNode></IndexListItems></Expand></Synthetic> <Synthetic Name="..." Condition="rows > 6"><DisplayString> </DisplayString></Synthetic> <Synthetic Name="row[-3]" Condition="rows > 6"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((short*)data)[$i+(rows-3)*cols])</ValueNode></IndexListItems></Expand></Synthetic> <Synthetic Name="row[-2]" Condition="rows > 6"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((short*)data)[$i+(rows-2)*cols])</ValueNode></IndexListItems></Expand></Synthetic> <Synthetic Name="row[-1]" Condition="rows > 6"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((short*)data)[$i+(rows-1)*cols])</ValueNode></IndexListItems></Expand></Synthetic> </Expand> </Synthetic> <Synthetic Name="[detail]" Condition="dims == 2 && (flags & 7) == 4 && (flags & 16384) == 16384"><!-- 32S --> <Expand> <Synthetic Name="row[0]" Condition="rows > 0"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((int*)data)[$i+0*cols])</ValueNode></IndexListItems></Expand></Synthetic> <Synthetic Name="row[1]" Condition="rows > 1"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((int*)data)[$i+1*cols])</ValueNode></IndexListItems></Expand></Synthetic> <Synthetic Name="row[2]" Condition="rows > 2"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((int*)data)[$i+2*cols])</ValueNode></IndexListItems></Expand></Synthetic> <Synthetic Name="row[3]" Condition="rows > 3 && rows < 7"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((int*)data)[$i+3*cols])</ValueNode></IndexListItems></Expand></Synthetic> <Synthetic Name="row[4]" Condition="rows > 4 && rows < 7"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((int*)data)[$i+4*cols])</ValueNode></IndexListItems></Expand></Synthetic> <Synthetic Name="row[5]" Condition="rows > 5 && rows < 7"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((int*)data)[$i+5*cols])</ValueNode></IndexListItems></Expand></Synthetic> <Synthetic Name="..." Condition="rows > 6"><DisplayString> </DisplayString></Synthetic> <Synthetic Name="row[-3]" Condition="rows > 6"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((int*)data)[$i+(rows-3)*cols])</ValueNode></IndexListItems></Expand></Synthetic> <Synthetic Name="row[-2]" Condition="rows > 6"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((int*)data)[$i+(rows-2)*cols])</ValueNode></IndexListItems></Expand></Synthetic> <Synthetic Name="row[-1]" Condition="rows > 6"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((int*)data)[$i+(rows-1)*cols])</ValueNode></IndexListItems></Expand></Synthetic> </Expand> </Synthetic> <Synthetic Name="[detail]" Condition="dims == 2 && (flags & 7) == 5 && (flags & 16384) == 16384"><!-- 32F --> <Expand> <Synthetic Name="row[0]" Condition="rows > 0"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((float*)data)[$i+0*cols])</ValueNode></IndexListItems></Expand></Synthetic> <Synthetic Name="row[1]" Condition="rows > 1"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((float*)data)[$i+1*cols])</ValueNode></IndexListItems></Expand></Synthetic> <Synthetic Name="row[2]" Condition="rows > 2"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((float*)data)[$i+2*cols])</ValueNode></IndexListItems></Expand></Synthetic> <Synthetic Name="row[3]" Condition="rows > 3 && rows < 7"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((float*)data)[$i+3*cols])</ValueNode></IndexListItems></Expand></Synthetic> <Synthetic Name="row[4]" Condition="rows > 4 && rows < 7"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((float*)data)[$i+4*cols])</ValueNode></IndexListItems></Expand></Synthetic> <Synthetic Name="row[5]" Condition="rows > 5 && rows < 7"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((float*)data)[$i+5*cols])</ValueNode></IndexListItems></Expand></Synthetic> <Synthetic Name="..." Condition="rows > 6"><DisplayString> </DisplayString></Synthetic> <Synthetic Name="row[-3]" Condition="rows > 6"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((float*)data)[$i+(rows-3)*cols])</ValueNode></IndexListItems></Expand></Synthetic> <Synthetic Name="row[-2]" Condition="rows > 6"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((float*)data)[$i+(rows-2)*cols])</ValueNode></IndexListItems></Expand></Synthetic> <Synthetic Name="row[-1]" Condition="rows > 6"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((float*)data)[$i+(rows-1)*cols])</ValueNode></IndexListItems></Expand></Synthetic> </Expand> </Synthetic> <Synthetic Name="[detail]" Condition="dims == 2 && (flags & 7) == 6 && (flags & 16384) == 16384"><!-- 64F --> <Expand> <Synthetic Name="row[0]" Condition="rows > 0"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((double*)data)[$i+0*cols])</ValueNode></IndexListItems></Expand></Synthetic> <Synthetic Name="row[1]" Condition="rows > 1"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((double*)data)[$i+1*cols])</ValueNode></IndexListItems></Expand></Synthetic> <Synthetic Name="row[2]" Condition="rows > 2"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((double*)data)[$i+2*cols])</ValueNode></IndexListItems></Expand></Synthetic> <Synthetic Name="row[3]" Condition="rows > 3 && rows < 7"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((double*)data)[$i+3*cols])</ValueNode></IndexListItems></Expand></Synthetic> <Synthetic Name="row[4]" Condition="rows > 4 && rows < 7"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((double*)data)[$i+4*cols])</ValueNode></IndexListItems></Expand></Synthetic> <Synthetic Name="row[5]" Condition="rows > 5 && rows < 7"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((double*)data)[$i+5*cols])</ValueNode></IndexListItems></Expand></Synthetic> <Synthetic Name="..." Condition="rows > 6"><DisplayString> </DisplayString></Synthetic> <Synthetic Name="row[-3]" Condition="rows > 6"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((double*)data)[$i+(rows-3)*cols])</ValueNode></IndexListItems></Expand></Synthetic> <Synthetic Name="row[-2]" Condition="rows > 6"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((double*)data)[$i+(rows-2)*cols])</ValueNode></IndexListItems></Expand></Synthetic> <Synthetic Name="row[-1]" Condition="rows > 6"> <Expand><IndexListItems><Size>cols</Size><ValueNode>(&((double*)data)[$i+(rows-1)*cols])</ValueNode></IndexListItems></Expand></Synthetic> </Expand> </Synthetic> <Item Name="[stride]">step.p[0]</Item> <Item Name="[continous]">(flags & 16384) == 16384</Item> <Item Name="[submatrix]">(flags & 32678) == 32678</Item> <Item Name="[refcount]">refcount</Item> <Item Name="[data]">data</Item> </Expand> </Type> ・・・
natvisファイルではループ等は使えないため、ゴリゴリ書いています。
今回はcv::Matの中身を6行(上3行、下3行)を見るためのnatvisを(ゴリゴリ)書きました。
他にも色々と可視化したほうがいいような気もしますが、
私個人としてはcv::Matさえ確認できればそれで良いのでこのままです。
必要なら自分で足してください。
これを適用すると、こんな感じになります。
大きな行列の中身を見るときに便利になりました!
めでたしめでたし。
Ubuntu 12.04(64bit)にjperlを導入する方法
ちょっと前にjperlなるものを使わざるを得ない機会がありました。
その時に導入に一晩くらいかかってしまったので、その詳細を書いておきます。
そもそもjperlとは何なのか・・・
つまり、負の遺産というわけですね・・・
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系は優秀
挨拶
私がプログラミング等でつまずいたところをメモするブログです。
同じ問題で苦しんでいる人の助けになれば幸いです・・・が、私自身はいろいろと力不足なので突っ込んだ質問などには答えられないかもしれません。
動けばそれで良いのです。
もし、誤り等あればコメントしていただければ幸いです。
それでは、よろしくお願いいたします。