I wanted to convert an IplImage into cv::Mat, all work except a little segfault when trying to delete the original buffer, tought i set the copy flag to true ...
I'm sure i'm doing something wrong, but i don't figure out ...
Here is what I do :
IplImage* cvImage = cvCreateImage( cvSize(width, height), IPL_DEPTH_8U, 3) ;
{... fill cvImage data by mcopy from a blob ...}
cv::Mat mat = cv::cvarrToMat(cvImage, true) ;
if (cvImage)
delete (cvImage) ;
Maybe I misanderstood the copy thing, and only tge cvImage->data can be delete, not the whole object ?
Thanks :)
in opencv if you create a IplImage* with cvCreateImage you should not free it with delete. try:
cvReleaseImage( &cvImage );
Because IplImage* is from the C-api you should free them as suggested. You have to do &cvImage. You can see that from the documentation: http://docs.opencv.org/modules/core/doc/old_basic_structures.html?highlight=cvreleaseimage#releaseimage
Related
I have graped an image from videoCapture object then i converted it to QImage to send it to server. After i receive it from the server side i want to do some image processing on the received image which is QImage. So before i performing any processing i have to convert it back to cv::Mat image.
I have function converting cv::Mat to QImage
// Copy input Mat
const uchar *qImageBuffer = (const uchar*)mat.data;
// Create QImage with same dimensions as input Mat
QImage img(qImageBuffer, mat.cols, mat.rows, mat.step, QImage::Format_RGB888);
//en
img.bits();
return img.rgbSwapped();
have function converting QImage to cv::Mat
Mat QImageToMat(const QImage& src){
cv::Mat tmp(src.height(),src.width(),CV_8UC3,(uchar*)src.bits(),src.bytesPerLine());
cv::Mat result = tmp ; // deep copy just in case (my lack of knowledge with open cv)
for (int i=0;i<src.height();i++) {
memcpy(result.ptr(i),src.scanLine(i),src.bytesPerLine());
}
cvtColor(result, result,CV_RGB2BGR);
return result;
}
I have been searching for about 2 days how to convert QImage to cv::Mat but with no luck non of the code snippet works for me. I don't know why, the image after conversion looks bad. you can see the image to left.
Does someone have any idea, about what could be cause the problem? Thanks in advance.
LEFT:image after converted from QImage to Mat RIGHT: the origranl Image which is in QImage format
I am implementing some methods and i'm using OpenCv functions.
I work with many frames of a video and i need to implement the best code to avoid some problems with the memory. I have some doubts:
Doubt 1: How would it be better?
Option 1:
IplImage* image1 = NULL;
...
IplImage* picture_sintetica(.. ){
...
if (image1 == NULL){
image1 = cvCreateImage( cvSize(width, height), IPL_DEPTH_8U, 3);
}
...
}
Option 2:
IplImage* image1 = NULL;
...
IplImage* picture_sintetica(...){
...
image1 = cvCreateImage( cvSize(width, height), IPL_DEPTH_8U, 3);
...
cvReleaseImage(&image1);
}
I think that in option 2, the image1 is created many times(each time the method named picture_sintetica is called) and with the option 1 it will be created only once, but I'm not sure...and in other examples i've seen using the option 2.
Doubt 2: Is it equivalent declare the image equal to zero (IplImage* image1 = 0;), to NULL (IplImage* image1 = NULL;) o to put anything (IplImage* image1;)?
Doubt 3: When is it recommendable to use the function named cvCloneImage and when is it better to use cvCopy?
Thanks so much!
Starting from Doubt3, according with opencv documentation, you should use cvCloneImage when you need a full copy of an image (including header, data and ROI).
Doubt1: looking at your code, there'are no reason to think image1 should created many times, unless your code is in a cicle.
Doubt2: i suggest to take a look to this answer
The camera keeps on crashing when I run my code. Trying to convert cv::mat to IplImage.
cv::Mat canvas(320, 240, CV_8UC3, Scalar(255,255,255));
IplImage test =canvas;
while(true )
{
canvas =cvQueryFrame(capture);
imgScribble = cvCreateImage(cvGetSize(&test), 8, 3);
IplImage* imgYellowThresh1 = GetThresholdedImage1(&test);
cvAdd(&test,imgScribble,&test);
cvShowImage("video", &test);
//This is the only line that uses the C++ API, so I assume you want to use the C API instead
cv::Mat canvas(320, 240, CV_8UC3, Scalar(255,255,255));
//I have used OpenCV for quite a while now and I've always declared IplImage*, and never IplImage. Use it safely as a rule of thumb, * always goes after IplImage
IplImage test =canvas;
This will become:
//although why you need to clone a newly created
//blank image is a valid concern
IplImage* canvas = cvCreateImage(....);
IplImage* test = cvClone(canvas);
cvZero(test);
//don't forget to release resources at some point
cvReleaseImage(&canvas);
cvReleaseImage(&test);
I am trying to capture video into a Mat type from two or more MSFT LifeCam HD-3000s using the videoInput library, OpenCV 2.4.3, and VS2010 Express.
I followed the example at: Most efficient way to capture and send images from a webcam in a network and it worked great.
Now I want to replace the IplImage type with a c++ Mat type. I tried to follow the example at: opencv create mat from camera data
That gave me the following:
VI = new videoInput;
int CurrentCam = 0;
VI->setupDevice(CurrentCam,WIDTH,HEIGHT);
int width = VI->getWidth(CurrentCam);
int height = VI->getHeight(CurrentCam);
unsigned char* yourBuffer = new unsigned char[VI->getSize(CurrentCam)];
cvNamedWindow("test",1);
while(1)
{
VI->getPixels(CurrentCam, yourBuffer, false, true);
cv::Mat image(width, height, CV_8UC3, yourBuffer, Mat::AUTO_STEP);
imshow("test", image);
if(cvWaitKey(15)==27) break;
}
The output is a lined image (i.e., it looks like the first line is correct but the second line seems off, third correct, fourth off, etc). That suggests that either the step part is wrong or there is some difference between the IplImage type and the Mat type that I am not getting. I have tried looking at/altering all the parameters, but I can't find anything.
Hopefully, an answer will help those facing what appears to be a fairly common issue with loading an image form the videoInput library to the Mat type.
Thanks in advance!
Try
cv::Mat image(height, width, CV_8UC3, yourBuffer, Mat::AUTO_STEP);
I have a pointer to image:
IplImage *img;
which has been converted to Mat
Mat mt(img);
Then, the Mat is sent to a function that gets a reference to Mat as input void f(Mat &m);
f(mt);
Now I want to copy back the Mat data to the original image.
Do you have any suggestion?
Best
Ali
Your answer can be found in the documentation here: http://opencv.willowgarage.com/documentation/cpp/c++_cheatsheet.html
Edit:
The first half of the first code area indeed talks about the copy constructor which you already have.
The second half of the first code area answers your question. Reproduced below for clarity.
//Convert to IplImage or CvMat, no data copying
IplImage ipl_img = img;
CvMat cvmat = img; // convert cv::Mat -> CvMat
For the following case:
double algorithm(IplImage* imgin)
{
//blabla
return erg;
}
I use the following way to call the function:
cv::Mat image = cv::imread("image.bmp");
double erg = algorithm(&image.operator IplImage());
I have made some tests and how it looks the image object will manage the memory. The operator IplImage() will only construct the header for IplImage. Maybe this could be useful?
You can use this form:
Your Code:
plImage *img;
Mat mt(img);
f(mt);
Now copy back the Mat data to the original image.
img->imageData = (char *) mt.data;
You can also copy the data instead of pointer:
memcpy(mt.data, img->imageData, (mt.rows*mt.cols));
(mt.rows*mt.cols) is the size that you should use for copy all data the mt to img.
Hope I helped