I have recently started with JavaCv using Android for camera preview image processing.
Basically, I take the camera preview, do some processing, convert it to HSV to modify some colors, and then I want to convert it to RGBA to fill a bitmap.
Everything works normally, but quite slow. In order to find the slowest part I made some measurements, and to my surprise found this line:
cvCvtColor( hsvimage, imageBitmap, CV_HSV2RGB); //<-- 50msecs
where hsvimage is a 3-channel IplImage, and imageBitmap is 4 channel.image. (The conversion is good and leaves the alpha channel to 255, giving an opaque bitmap as expected)
Just for comparison, the following two lines only take 3msec
cvCvtColor(yuvimage, bgrimage, CV_YUV2BGR_NV21);
cvCvtColor(bgrimage, hsvimage, CV_BGR2HSV);
(yuvimage is 1 channel IplImage, bgrimage and hsvimage are 3 channel IplImages)
It seems as if the first conversion (HSV2RGB) isn't so much optimized as others. Also tested it with a 3-channel destination image, just in case, but with the same results.
I would like to find a way to make it as fast as BGR2HSV. Possible ways:
- Find if there is another "equivalent" constant to CV_HSV2RGB which is faster
- Get direct access to the H-S-V byte arrays and make my own "fast" conversion in C.
Any idea to solve this issue will be welcome
--EDIT--
All this is happening with a small 320*240 image and running on a Xiaomi Redmi Note 4. Most of the operations such as converting color from RGB to HSV take less than 1 msec. Canny takes 5msec, Floodfill takes about 5 or 6 msec. It is only this conversion HSV2RGB which gives such strange results. Will try to use OpenCV directly (not JavaCV) to see if this behaviour disappears.
I was using an old JavaCV version (0.11) Now I have updated to 1.3 and results are nearly the same
...
long startTime=System.currentTimeMillis();
cvCvtColor(hsvimage, imageBitmap, CV_HSV2RGB);
Log.w(LOG_TAG, "Time:" + String.valueOf(System.currentTimeMillis() - startTime)); //<-- From 45 to 50msec
Log.w(LOG_TAG,"Channels:"+imageBitmap.nChannels()); // <-- returns 4
I can fill a 32bit/pixel android bitmap with the result
Mat mim4C= new Mat(imageBitmap);
Mat mhsvimage = new Mat(hsvimage);
long startTime**strong text**=System.currentTimeMillis();
CvtColor(mhsvimage, mim4C, CV_HSV2RGB);
Log.w(LOG_TAG, "Time:" + String.valueOf(System.currentTimeMillis() - startTime)); //<-- From 45 to 50mse
IplImage iim4C=new IplImage(mim4C);
Log.w(LOG_TAG,"Channels:"+iim4C.nChannels()); // <-- returns 3!!!
In this second case, if I try to fill a 32bits/pixel android bitmap (after converting back mim4C to IplImage), it crashes since it has 3 channels