0

I want to split an image into h,s and v channels. But an error occured every time and the reason seems to be that opencv split function does not work properly.

My code:

Mat src, srcHSV;
Mat srcH;
vector<Mat> channels;
VideoCapture cap(0);
for(int frame = 0; ; frame++)
{
    cap >> src;

    imshow("camera image", src);
    cvWaitKey(1);

    cvtColor(src, srcHSV, CV_BGR2HSV);
    imshow("hsv image", srcHSV);
    cvWaitKey(1);

    split(srcHSV, channels);
    srcH =  channels[0];
    ...  //do something with srcH
}

Camera image and hsv image are OK. But when it executes srcH = channels[0], an error message says:

Unhandled exception at 0x012d1602 in xxx.exe: 0xC0000005: Access violation reading location 0x00000014.

I set a breakpoint here and checked the value of channels. It comprises of many elements, but each element is an unknown object.
channels I saw a post talking about the similar problem but there was no answer. split image to 3 channels opencv error.

[solved]
According to @nowaqq 's comments and @Andrey Smorodov 's answer, my code now looks like this:

for(int frame =0 ; ; frame ++)
  {
    vector<Mat> channels; //put the channels declaration inside the for-loop

    cap >> src;

    imshow("camera image", src);
    cvWaitKey(1);
    srcHSV = Mat::zeros(Size(src.rows, src.cols), CV_8UC3);
    cvtColor(src, srcHSV, CV_BGR2HSV);
    imshow("hsv image", srcHSV);
    cvWaitKey(1);

    channels.clear();
    channels.resize(srcHSV.channels());  //resize channels
    cv::split(srcHSV, &channels[0]);  //&channels[0] instead of channels as the second parameter to split function
    srcH = channels[0];
    ...//do something with srcH
 }

[updated]
I struggled to solve another problem, this problem was also solved as a side-effect. See my answer below.

dudu
  • 801
  • 1
  • 10
  • 32
  • opencv doc says: "in the first variant of the function the number of arrays must match src.channels(); the arrays themselves are reallocated, if needed." Have you tried doing `channels.resize(srcHSV.channels())` before calling split? – nowaqq Oct 29 '17 at 11:25
  • @nowaqq Thank you for pointing that. I tried `channels.resized(srcHSV.channels()) before calling split` just now, `channels` now contains only three elements, but each element is still a very strange object with `dims`, 'rows' and `cols` all equaling to zero, and `data` a bad pointer. That means I cannot use `channels` or any channel. – dudu Oct 29 '17 at 11:35
  • 1
    Also, since split expects a pointer, I think you should pass &channels[0] instead of vector. – nowaqq Oct 29 '17 at 11:56
  • if srcHSV isn't empty, your code should work imho. Can you check your openCV installation?? Can you try a different openCV version? Can you try cv::split? Maybe there are multiple functions with name split in your environment? – Micka Oct 29 '17 at 16:06

2 Answers2

1

Put channels declaration into loop, split seems pushes more and more Mat into vector, and these Mats are become broken next iteration. Or clean it each time, before use split.

Andrey Smorodov
  • 10,649
  • 2
  • 35
  • 42
0

The solution seems unrelated to this question but indeed it solves the problem!
Since I'm debugging my image processing code, my solution configuration is debug and platform win32, but when I was configuring my project, to make it "more compatible", I add release and debug libs path, and add two versions of libs as dependency, for example, opencv_calib3d2412.lib(release version library) and opencv_calib3d2412d.lib(debug version library). In brief, I set up the opencv+vs2008+(C++ project) following this question on SO. By the way, Step 7 in that question description is really misleading. Or maybe I misunderstand it. After I remove the release lib path and release version libs from dependency, it works well.
The wrong configuration leads to another problem except the one I described above. The title of the window shows some strange charactors. To solve that problem, solution here saved me from all the weird things.

dudu
  • 801
  • 1
  • 10
  • 32