スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

OpenCV for Android で特定の色を抽出 (NDK)

書きました。

・ネイティブメソッドの記述
//色抽出
public static native void colorExtract(long matAddr,int code,
int lowH,int highH,
int lowS,int highS,
int lowV,int highV);

・ネイティブコード
JNIEXPORT void JNICALL Java_com_fc2_blog_zaburoapp_markerdetection_MainActivity_colorExtract
(JNIEnv * jenv, jclass, jlong matAddr, jint code, jint lowH, jint highH, jint lowS, jint highS, jint lowV, jint highV){

Mat *inputImg;
inputImg = (Mat*) matAddr;

int height = inputImg->rows;
int width = inputImg->cols;

Mat hsvImg = Mat(height,width,CV_8UC3);
cvtColor(*inputImg,hsvImg,code);

vector singleCh;
split(hsvImg,singleCh);

Mat h1,h2,h,s1,s2,s,v1,v2,v,hs,mask;
if(lowH<=highH){
threshold((Mat)singleCh[0],h1,lowH,255,CV_THRESH_BINARY);
threshold((Mat)singleCh[0],h2,highH,255,CV_THRESH_BINARY_INV);
bitwise_and(h1,h2,h);
}else{
threshold((Mat)singleCh[0],h1,lowH,255,CV_THRESH_BINARY);
threshold((Mat)singleCh[0],h2,highH,255,CV_THRESH_BINARY_INV);
bitwise_or(h1,h2,h);
}
if(lowS<=highS){
threshold((Mat)singleCh[1],s1,lowS,255,CV_THRESH_BINARY);
threshold((Mat)singleCh[1],s2,highS,255,CV_THRESH_BINARY_INV);
bitwise_and(s1,s2,s);
}else{
threshold((Mat)singleCh[1],s1,lowS,255,CV_THRESH_BINARY);
threshold((Mat)singleCh[1],s2,highS,255,CV_THRESH_BINARY_INV);
bitwise_or(s1,s2,s);
}
if(lowH<=highH){
threshold((Mat)singleCh[2],v1,lowV,255,CV_THRESH_BINARY);
threshold((Mat)singleCh[2],v2,highV,255,CV_THRESH_BINARY_INV);
bitwise_and(v1,v2,v);
}else{
threshold((Mat)singleCh[2],v1,lowV,255,CV_THRESH_BINARY);
threshold((Mat)singleCh[2],v2,highV,255,CV_THRESH_BINARY_INV);
bitwise_or(v1,v2,v);
}

bitwise_and(h,s,hs);
bitwise_and(hs,v,mask);

Mat dstImg = Mat(height,width,inputImg->type(),Scalar(0,0,0));
inputImg->copyTo(dstImg,mask);
dstImg.copyTo(*inputImg);

}

・使い方・例
Mat matImg = new Mat();
Utils.bitmapToMat(bmp,matImg);
colorExtract(matImg.getNativeObjAddr(),Imgproc.COLOR_RGB2HSV,
170,10,
80,255,
0,255);
Utils.matToBitmap(matImg, bmp);
mImageView.setImageBitmap(bmp);
って感じで使えば
色相(H):0〜10,170〜255
彩度(S):80〜255
明度(V):0〜255
の範囲の色を入力画像と同じサイズの黒背景の画像に抽出します。
第2引数のcodeはBitmapは大抵RGBのイメージだから
こんな感じにしとけば概ね間違いないと思います。
内部で、CV_8UC3(符号無し8bit整数3チャンネル)で画素を扱う都合上
色のパラメータは0〜255の範囲で表現します。
たぶん範囲外の値を渡すと落ちます。
例外投げる部分かけばよかったんですけど、めんどうでした。
スポンサーサイト

【Android】BitmapのgetPixels()について

分かりやすく解説しているページがあったのでメモ

しずくくんのAndroidでゲームプログラミングしてみたいなblog
Bitmap.getPixels()のstride引数の意味がわかった
http://blog.livedoor.jp/shizuku_kun/archives/51385763.html
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。