JavaCV Convert color HSV2RGB very slow

372 Views Asked by At

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

0

There are 0 best solutions below