How to convert cv::Mat to void* - c++

I am making a DLL in C++ to use it in LabView, I get an RGB image and I convert it to grayscale. My code is the following:
DLLIMPORT void function (void* ImageSrc, void* ImageF)
{
cv::Mat greyMat, colorMat;
colorMat = cv::Mat(488, 648, CV_8U, (uchar*)ImageSrc);
greyMat = (colorMat, CV_LOAD_IMAGE_GRAYSCALE);
}
ImageF would be the gray image and I do not know how to copy grayMat in ImageF.

According to the following post it supposed to be very simple:
DLLIMPORT void function(void* ImageSrc, void* ImageF)
{
cv::Mat colorMat = cv::Mat(488, 648, CV_8UC3, ImageSrc);
cv::Mat greyMat = cv::Mat(488, 648, CV_8UC1, ImageF);
cv::cvtColor(colorMat, greyMat, cv::COLOR_RGB2GRAY); //You may also try cv::COLOR_BGR2GRAY
}
The ImageSrc is RGB, so it is has 3 color channels, and the type should be CV_8UC3 and not CV_8U.
Create the gray cv::Mat with ImageF as data argument (and type CV_8UC1).
There are multiple options for creating cv:Mat objects (constructor overloading).
The above option sets ImageF to point the data of the image.
Execute cv::cvtColor with cv::COLOR_RGB2GRAY conversion type, for converting from RGB to gray.
Note:
The resolution of the output image (684x488) and the type (gray type with one byte per pixel) must be defined in LabView before executing the function.
The size and type information are not passed from function to LabView.
Only the "raw" image data is passed to LabView.
Please let me know if it works, because I have no way to test it.

Related

Read video frame with OpenCV to specified pointer (C++)

Is there a way to read a video frame with videocapture and specify where it should go in memory? Let's say given I have a pointer char *p and have preallocated the correct amount of memory for the frame, can I read in the frame to p's address?
cv::Mat is designed to handle memory management of images automatically, but it can also be used with externally allocated buffers. To do this, pass in a pointer to the external buffer to the Mat constructor.
Make sure the buffer size, Mat size, and type (channels, depth, etc.) match the output coming out of VideoCapture.
Example:
unsigned char *data; // Points to buffer of appropriate size.
cv::VideoCapture cap; // A valid capture
// This only allocates the Mat header with a reference to "data"
cv::Mat frame {
rows,
cols,
CV_8UC3, // image type, here 3-channel, 8 bits per channel, unsigned
data
};
cap >> frame; // Image data stored into buffer at "data"

How to convert Mat to cvMat in OpenCV 3.0

How can I convert an OpenCV Mat object to cvMat object ?
As per this OpenCV interoperability document(1), this conversion should be possible. But on declaring cvMat, compiler gives below error message at line cvMat deprecatedImg
: error: < expected ‘;’ before ‘deprecatedImg’ >,
How to fix this ?
In OpenCV 3 and above you have to use compatability headers(types_c.h) for using deprecated C objects like cvMat. In OpenCV 3.0, CvMat has a constructor which accepts a Mat(1). Code as below.
#include "opencv2/core/types_c.h"
cv::Mat img = ... ;
CvMat deprecatedImg(img);
In OpenCV 2.4.* and below, Mat to CvMat conversion operator(2) exists and you can simply assign a Mat to CvMat as below. Note that this conversion operator no more exists in OpenCV 3 and above.
Mat img = ...;
CvMat cvMatImg = img;

how to convert from cv::Mat to CvArr?

i have passed a lot of time searching on how to convert from cv::Mat or CvMat to CvArr but with no gain ,please help me in that,thanks.
Mat img = imread("C:\MyPic.jpg",CV_LOAD_IMAGE_GRAYSCALE);
IplImage tmp=img;
cvErode(&tmp, &tmp, 0, 2);
Mat laser=&tmp;
imshow("Eroded",laser);
I converted cv::Mat to CvArr by this way. Instead of using tmp directly use &tmp.
When I need to do that I just use :
IplImage tmp = image;
With image a Mat variable.
If I recall correctly, CvMat IS a CvArr so you can just cast it into a CvArr, and the first bytes of the now CvArr tell the function that it is actually a CvMat:
http://opencv.willowgarage.com/documentation/basic_structures.html#cvarr
Are you sure you want to convert it? sometimes there is equivalent function that use what you have. For example cvMorphologyEx is using CvArr but morphologyEx is using cv::Mat.
convert first the image using the following:
IplImage* oldstyleimg = &matimg.operator IplImage()
I don t remember if it only create the header for the image or it makes a copy

Opencv : Conversion Mat to IplImage for cvLabel

I have:
Mat *depthImage = new Mat(480, 640, CV_8UC1, Scalar::all(0));
And further in my code I do:
Mat image = *depthImage;
I do some OpenCV stuff with it and then I want to use cvBlob (so blob analysis). Though this function still uses IplImage and not Mat. So I wanted to convert them. I've read that I could just do this:
IplImage *blobimg = image;
But it doesn't work, I get this error:
Semantic Issue: No viable conversion from 'cv::Mat' to 'IplImage *' (aka '_IplImage *')
Eventually I want to be able to use this function on the newley created IplImage
cvLabel(<#const IplImage *img#>, <#IplImage *imgOut#>, <#CvBlobs &blobs#>)
As you can see the conversion from Mat to IplImage is required. But it is not working. My question is how do I fix this?
Thanks in advance
As Martin Beckett says in the comments, the cheatsheet shows this solution. There is no conversion from cv::Mat to IplImage *, but there is a conversion from cv::Mat to IplImage.
Change the line
IplImage *blobimg = image;
to
IplImage blobimg = image;
and it should compile.
When calling cvLabel, pass the parameter like
cvLabel(&blobimg, ...);

cvShowImage error

Ok. With a help of SO I have managed to put together this code. There is one more error though:
// ...
std::vector<char> jpegBuffer(lSize);
// copy the file into the buffer.
fread(&jpegBuffer[0], 1, jpegBuffer.size(), pFile);
// terminate
fclose (pFile);
Mat matrixJpeg = cv::imdecode(Mat(jpegBuffer), 1);
IplImage fIplImageHeader = matrixJpeg;
cvShowImage("Video", fIplImageHeader);
char key = cvWaitKey();
There is one more error with this code though. It is at this line:
cvShowImage("Video", fIplImageHeader);
And the error is:
/home/richard/Desktop/richard/client/src/main.cc:106: error: cannot convert ‘IplImage’ to ‘const CvArr*’ for argument ‘2’ to ‘void cvShowImage(const char*, const CvArr*)’
According to the docs Mat and IplImage should be interchangable and this:
IplImage fIplImageHeader = matrixJpeg;
Should be all that is needed to convert Mat to IplImage.
I think it should be:
IplImage* fIplImageHeader = matrixJpeg;
IplImage* and Mat* should be interchangeable.
CvArr* is a typedef for void*
You must specify the forced type conversion:
csShowImage("Whatever", static_cast<CvArr*>(somePointer));
Also note that somePointer is a pointer.
You might say something like
IplImage object = matrix;
IplImage* somePointer = &object;
Also, I kind of doubt it that arbitrary image type is substitutable with a matrix type. What are you willing to achieve when you tell your program to show the matrix?