how to convert back QImage to cv::Mat - opencv

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

Related

normalize and convertScaleAbs insights in opencv

Mat img = imread("/home/akash/Desktop/coding/IP/openCV/chessBoard.jpg",1);
Mat gray;
int thresh = 200;
void corner_detect(int,void *){
Mat dst = Mat::zeros(gray.size(),CV_32FC1);
Mat dst_norm,dst_scale;
cornerHarris(gray,dst,2,3,0.04);
normalize(dst,dst_norm,0,255,NORM_MINMAX,CV_32FC1,Mat()); //????
convertScaleAbs(dst_norm,dst_scale); //????
namedWindow("dst_norm",CV_WINDOW_AUTOSIZE);
imshow("dst_norm",dst_norm);
for(int i=0;i<dst_norm.rows;i++){
for(int j=0;j<dst_norm.cols;j++){
if(dst_norm.at<float>(i,j) > thresh){
circle(dst_scale,Point(j,i),5,Scalar(0),2);
}
}
}
imshow("window",dst_scale);
}
int main(){
namedWindow("window",CV_WINDOW_AUTOSIZE);
namedWindow("input",CV_WINDOW_AUTOSIZE);
cvtColor(img,gray,CV_BGR2GRAY);
createTrackbar("threshold","window",&thresh,255,corner_detect);
corner_detect(0,0);
imshow("input",img);
waitKey(0);
return 0;
}
I have taken this code from here which is basically corner detection and drawing circles around it.
I want to ask(where "????" is mentioned in code) working of normalize and convertScaleAbs. I have read the docs but I am still in doubt.I also outputted the dst_norm but it helped me none.
I got that normalize is used to change the value range in array and convertScaleAbs is converting CV_32FC1 type image to CV_8UC1.
But i am unable to understand any insights(i.e. how i got dst_norm and dst_scale when i outputted them).
Any help would be appreciated....
screen shot for reference

Mat to IplImage crash

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);

OpenCV 2.4.3 and videoInput into Mat

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);

Converting Basler image to OpenCV

I'm trying to convert frames captured from a Basler camera to OpenCV's Mat format. There isn't a lot of information from the Basler API documentation, but these are the two lines in the Basler example that should be useful in determining what the format of the output is:
// Get the pointer to the image buffer
const uint8_t *pImageBuffer = (uint8_t *) Result.Buffer();
cout << "Gray value of first pixel: " << (uint32_t) pImageBuffer[0] << endl << endl;
I know what the image format is (currently set to mono 8-bit), and have tried doing:
img = cv::Mat(964, 1294, CV_8UC1, &pImageBuffer);
img = cv::Mat(964, 1294, CV_8UC1, Result.Buffer());
Neither of which works. Any suggestions/advices would be much appreciated, thanks!
EDIT: I can access the pixels in the Basler image by:
for (int i=0; i<1294*964; i++)
(uint8_t) pImageBuffer[i];
If that helps with converting it to OpenCV's Mat format.
You are creating the cv images to use the camera's memory - rather than the images owning their own memory. The problem may be that the camera is locking that pointer - or perhaps expects to reallocate and move it on each new image
Try creating the images without the last parameter and then copy the pixel data from the camera to the image using memcpy().
// Danger! Result.Buffer() may be changed by the Basler driver without your knowing
const uint8_t *pImageBuffer = (uint8_t *) Result.Buffer();
// This is using memory that you have no control over - inside the Result object
img = cv::Mat(964, 1294, CV_8UC1, &pImageBuffer);
// Instead do this
img = cv::Mat(964, 1294, CV_8UC1); // manages it's own memory
// copies from Result.Buffer into img
memcpy(img.ptr(),Result.Buffer(),1294*964);
// edit: cvImage stores it's rows aligned on a 4byte boundary
// so if the source data isn't aligned you will have to do
for (int irow=0;irow<964;irow++) {
memcpy(img.ptr(irow),Result.Buffer()+(irow*1294),1294);
}
C++ code to get a Mat frame from a Pylon cam
Pylon::DeviceInfoList_t devices;
... get pylon devices if you have more than a camera connected ...
pylonCam = new CInstantCamera(tlFactory->CreateDevice(devices[selectedCamId]));
Pylon::CGrabResultPtr ptrGrabResult;
Pylon::CImageFormatConverter formatConverter;
formatConverter.OutputPixelFormat = Pylon::PixelType_BGR8packed;
pylonCam->MaxNumBuffer = 30;
pylonCam->StartGrabbing(GrabStrategy_LatestImageOnly);
std::cout << " trying to get width and height from pylon device " << std::endl;
pylonCam->RetrieveResult(5000, ptrGrabResult, TimeoutHandling_ThrowException);
formatConverter.Convert(pylonImage, ptrGrabResult);
Mat temp = Mat(ptrGrabResult->GetHeight(), ptrGrabResult->GetWidth(), CV_8UC3, (uint8_t*)pylonImage.GetBuffer());

OpenCV Mat to IplImage* conversion

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

Resources