Question

I'm trying to convert an bgr mat to an hsv mat for some detection, but the hsv image keeps coming out blocky. Here is my code in c++:

int main() {
    const int device = 1;
    VideoCapture capture(device);
    Mat input;
    int key;
    if(!capture.isOpened()) {
        printf("No video recording device under device number %i found. Aborting program...\n", device);
        return -1;
    }
    namedWindow("Isolation Test", CV_WINDOW_AUTOSIZE);
    while(1) {
        capture >> input;
        cvtColor(input, input, CV_BGR2HSV);
        imshow("Isolation Test", input);
        key = static_cast<int>(waitKey(10));
        if(key == 27)
            break;
    }
    destroyWindow("Isolation Test");
    return 0;
}

Here is a snapshot of what the output looks like. the input does not look blocky when I comment out the cvtColor. What is the problem and what should I do to fix it?

Was it helpful?

Solution

I suggested an explanation in the comments part, but decided to actually verify my assumption and explain a little bit about the HSV color space.

There is no problem in the code nor in OpenCV's cvtColor. the "blocky" artifacts exist in the RGB image, but are not noticeable. All of the JPEG family compression algorithms produce these artifacts. The reason we usually don't see them is that the algorithms "exploit" weaknesses in our visual system and compress more stuff that we are not very sensitive to.

I converted the image back to RGB using OpenCVscvtColor` and the artifacts magically disappeared (images are below).

The HSV color space in particular has several characteristics that exaggerate these artifacts. The important of which is probably the fact that wherever the V channel (Value/Luminance) is very low, the H & S channels are very unstable and are quite meaningless. In the extreme: [128,255,0] == [0,0,0].

So very small and unnoticeable compression artifacts in the dark areas of the image become very prominent with the false colors of the HSV color space.

If you want to use the HSV color space as feature space for color comparison keep in mind that if V is very low, H & S are quite meaningless. That is also true for very low S values that make the H value meaningless ([0,0,100] == [128,0,100]).

BTW. also keep in mind that the H channel is cyclic and the difference between H == 0 and H == 255 is only one gray level.

  • False colors "blocky" HSV image posted in the question HSV image posted by @scribblemaniac
  • Image converted back to RGB using cvtColor Same image after conversion back to RGB

OTHER TIPS

I think this happen because the imshow function will always interpret the image as a simple RGB or BGR image. So you need to change back HSV to BGR using cvtColor(input,input,CV_HSV2BGR) before show image.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top