0

I am currently doing some C++ image processing with openCV. I developed the application on a Mac with Xcode 6.3.2 and it works perfectly in both debug and release. In order to have a Windows executable program, I am now working on Windows with Visual Studio Express 2013. The program is running well on debug mode but crashes in release mode on this part of the code :

#include "stdafx.h"
#include "math.h"
#include <iostream>
#include "opencv2/core/core.hpp"
#include "opencv2/core/core_c.h"
#include "opencv2/opencv.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/highgui/highgui_c.h"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/imgproc/imgproc_c.h"
#include "opencv2/photo/photo.hpp"
#include "opencv2/features2d/features2d.hpp"


using namespace cv;
using namespace std;

int main(int argc, const char** argv)
{

vector<Mat> stacked_images;
Mat medianr_eq, mediang_eq, medianb_eq, objrgb;

medianr_eq = imread("C:\\Path\\medianr_eq.png", CV_LOAD_IMAGE_GRAYSCALE);
mediang_eq = imread("C:\\Path\\mediang_eq.png", CV_LOAD_IMAGE_GRAYSCALE);
medianb_eq = imread("C:\\Path\\medianb_eq.png", CV_LOAD_IMAGE_GRAYSCALE);

objrgb = Mat(medianr_eq.size(), CV_16UC3);

stacked_images.clear();

stacked_images.push_back(medianb_eq); /*B*/
stacked_images.push_back(mediang_eq); /*G*/
stacked_images.push_back(medianr_eq); /*R*/
merge(stacked_images, objrgb);

}

The error I get is :

OpenCV Error : Assertion failed <mv && n > 0> in cv::merge, file C:\builds\master_PackSlave_Win64-vc12-shared\opencv\modules\core\src\convert.cpp, line 941

I can't see where I could have done something wrong... Indeed, it is pretty basic OpenCV !

The images I used are downloadable with this link : https://transfert.u-psud.fr/gs67

For astronomy lovers it is the Stephan's Quintet, taken with Calar Alto Observatory's 1.23m telescope where I currently am an intern.

Thank you in advance for your help, Arnaud.

Nano
  • 1
  • 1
  • 2
  • you're declaring objrgb as CV_8UC1, while it should be CV_8UC3. However, merge should create it correctly... – Miki Aug 02 '15 at 21:53
  • Oh yes sorry, I changed it in the last minute... In fact, I was using CV_16UC3 (images are coded on 16bits) before and I had the same problem. I am going to edit my question. – Nano Aug 02 '15 at 21:57
  • Tried with your images. It works for me. You can however remove the line `objrgb = Mat(medianr_eq.size(), CV_16UC3);` since merge will create `objrgb` the correct size and type. – Miki Aug 02 '15 at 22:02
  • Also, `imread` loads CV_8UC3 images, not CV_16UC3 – Miki Aug 02 '15 at 22:03
  • Ok thanks a lot. Are you using Visual Studio ? Do you think the problem can come from the installation of my OpenCV libraries then ? – Nano Aug 02 '15 at 22:05
  • Yes. First thing, check if your project is 64 or 32 bit – Miki Aug 02 '15 at 22:06
  • It is 64 bits for me. – Nano Aug 02 '15 at 22:11
  • Usually this kind of things happens because you're using OpenCV compiled 64 bit and your project is 32 bit, or viceversa. Which OpenCV version? – Miki Aug 02 '15 at 22:13
  • I am using OpenCV 3.0 – Nano Aug 02 '15 at 22:17
  • Odd, it should work. If you have 10 minutes to waste, try reinstalling OpenCV and setup your VS project like [this](http://stackoverflow.com/a/31545237/5008845). – Miki Aug 02 '15 at 22:22
  • Ok, I will do it in about an hour. Thanks ! – Nano Aug 02 '15 at 22:24

2 Answers2

4

I recently had the exact same error, appearing with a valid openCV code running perfectly fine in debug mode but not in release mode.

Looking into the openCV source code, one can find that the function called has this code (modules/core/src/convert.cpp, line 341):

void cv::merge(InputArrayOfArrays _mv, OutputArray _dst)
{
    CV_OCL_RUN(_mv.isUMatVector() && _dst.isUMat(),
               ocl_merge(_mv, _dst))

    std::vector<Mat> mv;
    _mv.getMatVector(mv);
    merge(!mv.empty() ? &mv[0] : 0, mv.size(), _dst);
}

the last line here calls the function 'void cv::merge(const Mat mv, size_t n, OutputArray _dst)*', which has the infamous CV_Assert( mv && n > 0 ); instruction in its first line, causing the crash at runtime.

This error tells us that the vector of Mat is either a null pointer/reference or empty, which it clearly isn't in your code. I strongly suspect that the error is in the getMatVector function call, not copying the contents of _mv into mv. This leaves an empty array that is passed to the merge function, causing the error raised by CV_Assert.

In my case, the fix was to use directly the prototype of the function defined at line 200 in convert.cpp. For you, that would mean (copying only the last few lines of your code):

stacked_images.clear();

stacked_images.push_back(medianb_eq); /*B*/
stacked_images.push_back(mediang_eq); /*G*/
stacked_images.push_back(medianr_eq); /*R*/
merge(&stacked_images[0], stacked_images.size(), objrgb);

This solution worked in my case, and my code is now happily running in debug and release mode !

PS: I know it has been a while, but thought I would post the answer anyway in case somebody running into the same problem would arrive on this SO question.

PS2: Here is a full example code:

#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>

using namespace cv;


int main( int argc, char** argv )
{
    namedWindow( "Display window", WINDOW_AUTOSIZE );

    Mat result;

    Mat R = imread("Lenna.png", CV_LOAD_IMAGE_GRAYSCALE);
    Mat G = imread("Lenna.png", CV_LOAD_IMAGE_GRAYSCALE);
    Mat B = imread("Lenna.png", CV_LOAD_IMAGE_GRAYSCALE);

    // Changing channel values for final result that should look largely blue
    R = 0.1*R;
    G = 0.1*G;
    B = 1.5*B;

    std::vector<cv::Mat> array_to_merge ;

    array_to_merge.push_back(B);
    array_to_merge.push_back(G);
    array_to_merge.push_back(R);

    // This line triggers a runtime error in Release mode
    //cv::merge(array_to_merge,result); 

    // This line works both in Release and Debug mode   
    cv::merge(&array_to_merge[0], array_to_merge.size(), result);


    cv::imshow( "Display window", result );
    cv::waitKey(0);
}
Ben
  • 441
  • 3
  • 10
0

Although you could write it in a lot fewer lines , this code is valid.

TimZaman
  • 2,689
  • 2
  • 26
  • 36