displaying hsv

763 views
Skip to first unread message

Radek Chudziak

unread,
Oct 25, 2011, 10:16:17 AM10/25/11
to android-opencv
That's the native code I am using to convert rgb to hsv


using namespace std;
using namespace cv;

extern "C" {
JNIEXPORT void JNICALL
Java_org_opencv_samples_tutorial3_Sample3View_FindFeatures(JNIEnv*
env, jobject thiz, jint width, jint height, jbyteArray yuv, jintArray
bgra)
{
jbyte* _yuv = env->GetByteArrayElements(yuv, 0);
jint* _bgra = env->GetIntArrayElements(bgra, 0);


Mat myuv(height + height/2, width, CV_8UC1, (unsigned char
*)_yuv);
Mat mbgra(height, width, CV_8UC4, (unsigned char *)_bgra);
Mat mgray(height, width, CV_8UC1, (unsigned char *)_yuv);


//Please make attention about BGRA byte order
//ARGB stored in java as int array becomes BGRA at native level
cvtColor(myuv, mbgra, CV_YUV420sp2BGR, 4);

Mat mhsv = Mat(mbgra.rows,mbgra.cols,CV_8UC4);
cvtColor(mbgra, mhsv, CV_BGR2HSV, 4);



env->ReleaseIntArrayElements(bgra, _bgra, 0);

env->ReleaseByteArrayElements(yuv, _yuv, 0);
}

}


How to make the device display the hsv colour on the screen rather
than rgb?

Andrey Pavlenko

unread,
Oct 26, 2011, 1:42:09 AM10/26/11
to android...@googlegroups.com
In the lines:
    Mat mhsv = Mat(mbgra.rows,mbgra.cols,CV_8UC4); 
    cvtColor(mbgra, mhsv, CV_BGR2HSV, 4); 
why do you use 4 channel Mat? looks like 3 channel is enough, i.e.
    Mat mhsv = Mat(mbgra.rows,mbgra.cols,CV_8UC3); 
    cvtColor(mbgra, mhsv, CV_BGR2HSV, 3); 

Anyway, I don't know a way to display HSV picture without conversion to RGB space

Radek Chudziak

unread,
Oct 26, 2011, 5:41:03 AM10/26/11
to android-opencv
So how to do that with the conversion to RGB? because when I convert
it to RGB it displays a normal RGB picture but what I want to achieve
is to see the hsv image and manipulate the hsv values to filter out
some of the colors. The goal of that is skin detection.

On Oct 26, 6:42 am, Andrey Pavlenko <andrey.pavle...@itseez.com>
wrote:
> In the lines:
>     Mat mhsv = Mat(mbgra.rows,mbgra.cols,*CV_8UC4*);
>     cvtColor(mbgra, mhsv, CV_BGR2HSV, *4*);
> why do you use 4 channel Mat? looks like 3 channel is enough, i.e.
>     Mat mhsv = Mat(mbgra.rows,mbgra.cols,*CV_8UC3*);
>     cvtColor(mbgra, mhsv, CV_BGR2HSV, *3*);

Andrey Pavlenko

unread,
Oct 26, 2011, 9:36:26 AM10/26/11
to android...@googlegroups.com
OK, if actually you'd like to visualize not an original picture but H, S and V values - 
I'd suggest you conversion RGBA2HSV (or HSV_FULL), 
than split 3-channel HSV image into 3 separate 1-channel Mats, 
then visualizing them all as separate gray-scale pictures.

BTW, I know some people use expressions in RGB color space for skin-detector purposes. This can be less accurate but faster.

Radek Chudziak

unread,
Oct 26, 2011, 10:30:43 AM10/26/11
to android...@googlegroups.com
The problem I am having is how to visualize them? Since in android
mRgba is the data structure that is displayed on the screen. How to
convert mRgba to either H,S or V? I would be grateful if you show me
an example.

2011/10/26 Andrey Pavlenko <andrey....@itseez.com>:

Shervin Emami

unread,
Oct 27, 2011, 2:13:33 AM10/27/11
to android-opencv
Hi Radek, you can look at my skin detection tutorial at "http://
www.shervinemami.info/blobs.html", the sample code is not for Android,
but if you run the code on a desktop you can get some ideas of what
you want to visualize, such as displaying H, S and V channels as
grayscale images, or perhaps to combine them in special ways such as
if you compile the code with "SHOW_EXTENDED_COLOR_IMAGES = true" to
get colorful visualizations.

-Shervin.


On Oct 27, 1:30 am, Radek Chudziak <chudy...@gmail.com> wrote:
> The problem I am having is how to visualize them? Since in android
> mRgba is the data structure that is displayed on the screen. How to
> convert mRgba to either H,S or V? I would be grateful if you show me
> an example.
>
> 2011/10/26 Andrey Pavlenko <andrey.pavle...@itseez.com>:

Andrey Pavlenko

unread,
Oct 27, 2011, 3:54:13 AM10/27/11
to android...@googlegroups.com
If you're asking how to display a single channel image in Android - I'd suggest you conversion it to a 4-channel one with cvtColor(GRAY2RGBA) and displaying like ARGB_8888.

Radek Chudziak

unread,
Oct 27, 2011, 7:59:51 AM10/27/11
to android-opencv
In android I am using the following code

capture.retrieve(mRgba, Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA);
Imgproc.cvtColor(mRgba, mhsv, Imgproc.COLOR_RGB2HSV_FULL, 0);
Imgproc.cvtColor(mhsv, mRgba, Imgproc.COLOR_HSV2RGB_FULL, 0);

Bitmap bmp = Bitmap.createBitmap(mRgba.cols(), mRgba.rows(),
Bitmap.Config.ARGB_8888);

if (Utils.matToBitmap(mRgba, bmp))
return bmp;

bmp.recycle();

But the output is messed up.


But it works fine when I convert it into grayscale using:
Imgproc.cvtColor(mRgba, mGray, Imgproc.COLOR_RGBA2GRAY, 4);
Imgproc.cvtColor(mGray, mRgba, Imgproc.COLOR_GRAY2RGBA, 4);

On Oct 27, 8:54 am, Andrey Pavlenko <andrey.pavle...@itseez.com>
wrote:

Andrey Pavlenko

unread,
Oct 27, 2011, 9:05:32 AM10/27/11
to android...@googlegroups.com
Sorry, I really can't understand what you're doing...

capture.retrieve(mRgba, Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA); 
Imgproc.cvtColor(mRgba, mhsv, Imgproc.COLOR_RGB2HSV_FULL, 0);
List<Mat> lhsv = new ArrayList<Mat>(3);
Core.split(mhsv, lhsv);
Mat mh = lhsv.get(0);
  //Mat ms = lhsv.get(1);
  //Mat mv = lhsv.get(2);
Mat mh4 = new Mat();
Imgproc.cvtColor(mh, mh4, Imgproc.COLOR_GRAY2RGBA, 4);
// convert mh4 to Bitmap and show your H values as grayscale picture
// the same way you can see S and V...

Radek Chudziak

unread,
Oct 27, 2011, 9:46:43 AM10/27/11
to android...@googlegroups.com
Great, that is one of the effects I wanted to achieve. But the other
one is to display the whole HSV image not just the particular single
channels. Like you can display an RGB picture and gray picture I want
to display HSV picture. Is it clear what I am aiming for? Something
like here http://www.roborealm.com/help/HSV_Channel.php what you can
see at the bottom of the page where RGB is displayed as HSV.

2011/10/27 Andrey Pavlenko <andrey....@itseez.com>:

Andrey Pavlenko

unread,
Oct 27, 2011, 11:06:13 AM10/27/11
to android...@googlegroups.com
OK, then after
Imgproc.cvtColor(mRgba, mhsv, Imgproc.COLOR_RGB2HSV_FULL);
you probably need
Imgproc.cvtColor(mhsv, mhsv4, Imgproc.COLOR_RGB2RGBA);
then convert 4-channel 'mhsv4' to Bitmap and display.

Radek Chudziak

unread,
Oct 28, 2011, 6:53:25 AM10/28/11
to android...@googlegroups.com
http://imageshack.us/photo/my-images/39/sc20111028114835hn.jpg/ that's
the output I am getting. It doesn't look like HSV to me?

2011/10/27 Andrey Pavlenko <andrey....@itseez.com>:

Andrey Pavlenko

unread,
Oct 28, 2011, 8:01:40 AM10/28/11
to android...@googlegroups.com
it looks like you exchanged H and V... 
make sure you used COLOR_RGB2RGBA in the last stage but not COLOR_RGB2BGRA
try the other one as well...

Radek Chudziak

unread,
Oct 28, 2011, 8:25:29 AM10/28/11
to android...@googlegroups.com
Or maybe that picture actually is the right HSV image. I compared it
to a program run on the laptop that converts and displays the hsv and
the pictures are very similar. One thing that is confusing me is the
code used for converting hsv to rgba which is COLOR_RGB2RGBA. I know
as the final result is displayed as RGBA so this needs to be the final
format but if not your help I would never figure that out. I was
trying converting rgba to rgb then rgb to hsv then hsv to rgb and back
to rgba but it wasn't working. Can you please explain why it is using
RGB2RGBA to convert hsv into rgba as it is a bit strange to me. Anyway
thanks a lot for your previous help!

2011/10/28 Andrey Pavlenko <andrey....@itseez.com>:

Andrey Pavlenko

unread,
Oct 28, 2011, 10:32:41 AM10/28/11
to android...@googlegroups.com
The 'hsv' is a 3-channel Mat, but to display it in Android you need to make it 4-channel.
COLOR_RGB2RGBA does exactly what you need: it just adds the 4th channel (alpha) keeping the other 3 ones as is.
Actually all the work could be done by one step if cvtColor had not ignored the last argument in RGB2HSV mode. But in the current implementation its HSV output always has 3 channels. So we need to call it again (RGB2RGBA) to add the 4th channel.

Radek Chudziak

unread,
Nov 3, 2011, 11:27:47 AM11/3/11
to android-opencv
I am having a problem. When the app runs for about 1 minute it just
turns off without returning any errors. It looks like there is a
memory leak or something. Do I have to deallocate the List<Mat> lhsv =
new ArrayList<Mat>(3); somehow just like the mats are deallocated
using the release method?

That's my code:

case ImageManipulationsActivity.VIEW_MODE_HSV:

capture.retrieve(mRgba, Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA);

//thresholding
Imgproc.cvtColor(mRgba, mhsv, Imgproc.COLOR_RGB2HSV_FULL, 0);

Core.split(mhsv, lhsv);

mh = lhsv.get(0);
ms = lhsv.get(1);
mv = lhsv.get(2);

Imgproc.threshold(mh, mh, ImageManipulationsActivity.H, 255, 3);
Imgproc.threshold(ms, ms, ImageManipulationsActivity.S, 255, 3);
Imgproc.threshold(mv, mv, ImageManipulationsActivity.V, 255, 3);

lhsv.clear();

lhsv.add(0, mh);
lhsv.add(1, ms);
lhsv.add(2, mv);

Core.merge(lhsv, mhsv);
Imgproc.cvtColor(mhsv, mRgba, Imgproc.COLOR_RGB2RGBA, 0);

break;



}

Bitmap bmp = Bitmap.createBitmap(mRgba.cols(), mRgba.rows(),
Bitmap.Config.ARGB_8888);


if (Utils.matToBitmap(mRgba, bmp))
return bmp;

bmp.recycle();
return null;
}

Then I deallocate all the mats but don't know whether to do anything
to the lhsv?

On Oct 28, 2:32 pm, Andrey Pavlenko <andrey.pavle...@itseez.com>
wrote:

Radek Chudziak

unread,
Nov 4, 2011, 8:00:46 AM11/4/11
to android-opencv
I have found the error description.

11-04 11:41:49.460: ERROR/AndroidRuntime(17461): FATAL EXCEPTION: Thread-10
11-04 11:41:49.460: ERROR/AndroidRuntime(17461): CvException
[org.opencv.core.CvException:
/home/andreyk/OpenCV2/trunk/opencv_2.3.1.b2/modules/imgproc/src/color.cpp:2789:
error: (-215) scn == 3 || scn == 4 in function void cv::cvtColor(const
cv::_InputArray&, const cv::_OutputArray&, int, int)
11-04 11:41:49.460: ERROR/AndroidRuntime(17461): ]
11-04 11:41:49.460: ERROR/AndroidRuntime(17461): at
org.opencv.imgproc.Imgproc.cvtColor_0(Native Method)
11-04 11:41:49.460: ERROR/AndroidRuntime(17461): at
org.opencv.imgproc.Imgproc.cvtColor(Imgproc.java:3484)
11-04 11:41:49.460: ERROR/AndroidRuntime(17461): at
org.opencv.samples.imagemanipulations.ImageManipulationsView.processFrame(ImageManipulationsView.java:151)
11-04 11:41:49.460: ERROR/AndroidRuntime(17461): at
org.opencv.samples.imagemanipulations.SampleCvViewBase.run(SampleCvViewBase.java:103)
11-04 11:41:49.460: ERROR/AndroidRuntime(17461): at
org.opencv.samples.imagemanipulations.ImageManipulationsView.run(ImageManipulationsView.java:172)
11-04 11:41:49.460: ERROR/AndroidRuntime(17461): at
java.lang.Thread.run(Thread.java:1019)

2011/11/3 Radek Chudziak <chud...@gmail.com>:

Reply all
Reply to author
Forward
0 new messages