OpenCV2.3.1で画素の濃度値を扱う方法

1,624 views
Skip to first unread message

bocre...@yahoo.co.jp

unread,
May 22, 2012, 11:52:40 AM5/22/12
to 日本Androidの会
はじめて投稿させていただきます.ルール違反などが有りましたら教えてください.

早速本題です.
現在Eclipse3.6+OpenCV2.3.1によるアンドロイドアプリ開発に挑戦しています.
OpenCVには数々の便利なクラス,メソッドが最初から備わっていますが,画素値を直接いじっていきたいと考えています.
それで調べていったところ,BitmapからMatに移したあと濃度値の取得はget,代入はputを使えばいいことは分かりました.
ここでいくつか質問です.
値の代入,取得はもっと簡単にできないのでしょうか.(OpenCV1.0がmat(1,0)でできたように)
現在は
mat.get(0,0,array);
でarryの中身をいじったあと
    mat.put(0,0,array);
で戻しています.

またbyte型チャンネル数1(CV_8UC1)のmatにおいて濃度値を調べていたところ,max:127,min:-128なのに真っ白は-1,真
っ黒は0で表現されるようになっていました.(黒0→127→‐128→‐1白)
なぜ‐128が黒,127が白ではないのでしょうか.
もし‐128を黒,127を白にする方法があれば教えていただけないでしょうか.

最後に,画像にラプラシアンフィルタをかけるついでに最大,最小値を求めるだけのプログラムですが,問題があればご指摘いただけると幸いです.ちなみに
ラプラシアンフィルタは全然成功していません.

int型をbyte型にキャストするのは問題ないのでしょうか.
   Mat mat = Utils.bitmapToMat(src);
Imgproc.cvtColor(mat , mat, Imgproc.COLOR_RGB2GRAY);
Mat mat2 = new Mat(mat.rows(), mat.cols(), CvType.CV_8UC(1));

byte ary[] = new byte[256*192];
byte ary2[] = new byte[256*192];
mat.get(0, 0, ary);

int a=0,b;
byte max=-100,min=120;

for(int i = 2; i < mat.height()-2; i++){
for(int j = 2; j < mat.width()-2; j++){
a=i*mat.width()+j;
          //ラプラシアン
           b = (ary[a]*4-ary[a+1]-ary[a-1]-ary[a-mat.width()]-ary[a
+mat.width()]);
ary2[a] = (byte)b;

          //最大・最小
if(ary[a]>max)max=ary[a];
if(ary[a]<min)min=ary[a];

}
}
mat2.put(0, 0, ary2);

Keisuke SUZUKI

unread,
May 22, 2012, 2:04:45 PM5/22/12
to android-g...@googlegroups.com
神戸支部の鈴木です。
まず、Androidに関わる内容は含まれていないようなので
OpenCVコミュニティで質問されるとより良い回答えられるかもしれません。

> 値の代入,取得はもっと簡単にできないのでしょうか.(OpenCV1.0がmat(1,0)でできたように)
型がCV_8UC1のグレイ画像なら
image.at<uchar>(i,j) = val;
で画素にアクセスできます。i, j が座標、値がvalです。

カラー画像だと
image.at<cv::vec3b>(i,j)[channel] = val;
になると思います。

> またbyte型チャンネル数1(CV_8UC1)のmatにおいて濃度値を調べていたところ,max:127,min:-128なのに真っ白は-1,真

CV_8UC1は 「8」bitの「U」nsigned型の「C」hannel数 「1」のフォーマットを表しています。
unsigned型はつまり0~255まで取りうるわけで、min-128はとりえません。
つまり
> っ黒は0で表現されるようになっていました.(黒0→127→‐128→‐1白)
で書かれているカッコ内は黒0→255白というわけです。

ラプラシアンのコードは良くみていません。
cv::Laplacian つかいましょう。

以上

2012年5月23日 0:52 bocre...@yahoo.co.jp <bocre...@yahoo.co.jp>:
> --
> このメールは Google グループのグループ「日本Androidの会」の登録者に送られています。
> このグループに投稿するには、android-g...@googlegroups.com にメールを送信してください。
> このグループから退会するには、android-group-j...@googlegroups.com にメールを送信してください。
> 詳細については、http://groups.google.com/group/android-group-japan?hl=ja からこのグループにアクセスしてください。
>

Makoto Yamazaki

unread,
May 22, 2012, 8:57:44 PM5/22/12
to android-g...@googlegroups.com
zaki です。

> またbyte型チャンネル数1(CV_8UC1)のmatにおいて濃度値を調べていたところ,max:127,min:-128なのに真っ白は-1,真
> っ黒は0で表現されるようになっていました.(黒0→127→‐128→‐1白)
> なぜ‐128が黒,127が白ではないのでしょうか.
> もし‐128を黒,127を白にする方法があれば教えていただけないでしょうか.

ここだけ。

その濃度値が byte 型の b に入っているとしたら、 int b1 = b & 0xff; で 0(黒)-255(白) に変換できます。

一応こうなる理由を。
符号付き8bit整数(Java の byte型)だと 0 = 0b00000000, 127=0x01111111,
-128=0b10000000, -1=0b11111111
で、これに & 0xff すると、上記の8bit が符号を維持したまま(先頭のbitが0なら24bitの0を、1なら24bitの1を付加することで)
32bit に拡張されます。これの下 8bit のみを残すので int 型の b1 に 0-255 で格納されます。

--
YAMAZAKI Makoto

bocre...@yahoo.co.jp

unread,
May 25, 2012, 11:53:45 AM5/25/12
to 日本Androidの会
返事か遅くなり申し訳ありません.

結局,濃度値を0~255に変更して元に戻すことで処理していこうと思います.

以上お騒がせしました.
Reply all
Reply to author
Forward
0 new messages