OpenCv, get image information - c++

I am playing around with an open source openCv application. With the provided image sets, it works great, but when I attempt to pass it a live camera stream, or even recorded frames from that camera stream, it crashes. I assume that this is to do with the cv::Mat type, differing image channels, or some conversion that i am not doing.
The provided dataset is grey-scale, 8 bit, and so are my images.
The application expects grayscale (CV_8U).
My question is:
Given one of the (working) provided images, and one of my recorded (not working) images, what is the best way to compare them using opencv, to find out what the difference might be that is causing my crashes?
Thank you.
I have tried:
Commenting out this code (Which gave assertion errors)
if(mImGray.channels()==3)
{
cvtColor(mImGray,mImGray,CV_BGR2GRAY);
cvtColor(imGrayRight,imGrayRight,CV_BGR2GRAY);
}
else if(mImGray.channels()==4)
{
cvtColor(mImGray,mImGray,CV_BGRA2GRAY);
cvtColor(imGrayRight,imGrayRight,CV_BGRA2GRAY);
}
And replacing it with:
cv::Mat TempL;
mImGray.convertTo(TempL, CV_8U);
cvtColor(TempL, mImGray, CV_BayerGR2BGR);
cvtColor(mImGray, mImGray, CV_BGR2GRAY);
And the program crashes with no error...

You can try this code:
if ( mImGray.depth() != CV_8U )
mImGray.convertTo(mImGray, CV_8U);
if (mImGray.channels() == 3 )
{
cvtColor(mImGray, mImGray, COLOR_BGR2GRAY);
}
Or you can define a new Mat with create function and use that.

Related

Threshold function does not work OpenCV C++

I just want to do convert a gray image to a binary image. But threshold function gives me a totaly black image as a binary image. I want to get dark gray object.
What is wrong here?
Code:
Mat theFrame = imread("C:\\asdsss.png"); // opencv
Mat gray,binary;
cvtColor(theFrame, gray, CV_BGR2GRAY);
threshold(gray, binary, 150, 255, THRESH_BINARY);
imwrite("result.jpg",binary);
İnput image:
The code works perfectly fine. I ran you exact code on the image provided. There is no issue with it.
I got the following output by running your code. The only problem I can think of could be loading of image. Try to see your image using cv::imshow after loading it. Also try to convert your image into jpg format and then try loading it again. You can also try compiling and running the opencv thresholding sample.

polarToCart and cartToPolar functions in opencv

Hey I've a circular image that I want to make a cartesian in openCV.
I've successfully made it on matlab however I want to do it on OpenCV.
After some digging on internet. I figured out there are actually functions called logPolar, polarToCart and cartToPolar. However OpenCV official documentation is lack of information to use them. Since I don't really understand parameters those functions take I couldn't really use them
So could someone give me (actually I think a lot of people looking for it) appropriate example to use those functions please ?
Just in case I am sharing my sample image too.
thanks in advance
if you're using opencv3, you probably want linearPolar:
note, that for both versions, you need a seperate src and dst image (does not work inplace)
#include "opencv2/opencv.hpp" // needs imgproc, imgcodecs & highgui
Mat src = imread("my.png", 0); // read a grayscale img
Mat dst; // empty.
linearPolar(src,dst, Point(src.cols/2,src.rows/2), 120, INTER_CUBIC );
imshow("linear", dst);
waitKey();
or logPolar:
logPolar(src,dst,Point(src.cols/2,src.rows/2),40,INTER_CUBIC );
[edit:]
if you're still using opencv2.4, you can only use the arcane c-api functions, and need IplImage conversions (not recommended):
Mat src=...;
Mat dst(src.size(), src.type()); // yes, you need to preallocate here
IplImage ipsrc = src; // new header, points to the same pixels
IplImage ipdst = dst;
cvLogPolar( &ipsrc, &ipdst, cvPoint2D32f(src.cols/2,src.rows/2), 40, CV_INTER_CUBIC);
// result is in dst, no need to release ipdst (and please don't do so.)
(polarToCart and cartToPolar work on point coords, not images)

Match Image on Screen with Template Pictures

I'm looking to make a program that once run, will continuously look for an template image (stored in directory of program) to match in realtime with the screen. Once found, it will click on the image (ie the center of the coords of the best match). The images will be exact copies (size/color) so finding the match should not be very hard.
This process then continues with many other images and then resets to start again with the first image again but once I have the first part working I can just copy the code.
I have downloaded the OpenCV library as it has image matching tools but I am lost. Any help with writing some stub code or pointing me to a helpful resource is much appreciated. I have checked a lot of the OpenCV docs with no luck.
Thanks you.
If you think that the template image would not be very different in the current frame then you should use matchTemplate() of openCV. Its very easy to use and will give you good results.
Have a look here for complete explanation http://docs.opencv.org/doc/tutorials/imgproc/histograms/template_matching/template_matching.html
void start()
{
VideoCapture cap(0);
Mat image;
namedWindow(wndname,1);
for(;;)
{
Mat frame;
cap >> frame; // get a new frame from camera
"Load your template image here"
"Declare a result image here"
"Perform the templateMatching() between template image and frame and store the results of correlation in result image declared above"
char c = cvWaitKey(33);
if( c == 27 ) break;
}
}

OpenCV and working with Fourier transform dft()

I am trying to point-wise multiply fourier transforms of two separate images and then convert back to a normal image. I'm not very familiar with using the fourier transform in OpenCV but this is what I have at the moment. The last line where the output is shown causes an exception of type 'System.Runtime.InteropServices.SEHException' but I can't figure out how to fix it. I have tried various different parameters and functions at each stage but all seem either give an exception or an empty output. What am I doing wrong? Thanks for any help you can give me!
Mat dftInput1, dftImage1, dftInput2, dftImage2, multipliedDFT, inverseDFT, inverseDFTconverted;
image1.convertTo(dftInput1, CV_32F);
dft(dftInput1, dftImage1, DFT_COMPLEX_OUTPUT);
image2.convertTo(dftInput2, CV_32F);
dft(dftInput2, dftImage2, DFT_COMPLEX_OUTPUT);
multiply(dftImage1, dftImage2, multipliedDFT);
idft(multipliedDFT, inverseDFT, DFT_SCALE);
inverseDFT.convertTo(inverseDFTconverted, CV_8U);
imshow("Output", inverseDFTconverted);
imshow can't show 2 channel images, only 1,3,4 channel ones.
if you use DFT_COMPLEX_OUTPUT for the dft, you get a 2 channel image, applying the reverse idft again produces a 2channel(complex) Mat
no idea, why you get a 'System.Runtime.InteropServices.SEHException' though ( is that 'managed c++' ? )
convertTo() changes the type of the channels, but not their count (yea, surprise).
so, either restrict it to the real part:
idft(multipliedDFT, inverseDFT, CV_DFT_SCALE | CV_DFT_REAL_OUTPUT );
or split it , and throw only the real part at imshow:
Mat chan[2];
split( inverseDFTconverted, chan );
imshow("lalala", chan[0]);

OpenCV copyTo() mask error

I'm trying to paste a smaller image into a larger image, using masks in OpenCV 2.4 via C++.
Without a mask, I copy the small image to the larger image with the following code:
smallImage.copyTo(largeImage(cv::Rect(pt, smallImage.size()));
where pt has the type of cv::Point2f. It works perfectly. However, if I apply a mask:
smallImage.copyTo(largeImage(cv::Rect(pt, smallImage.size()), mask);
I get an error from Mat::create (see documentation):
CV_Assert(!fixedType() || (CV_MAT_CN(type) ==
m.channels() && ((1 << CV_MAT_TYPE(flags)) & fixedDepthMask) != 0));
If I remove the cv::Rect from my code, simplifying it to:
smallImage.copyTo(largeImage, mask);
it works, albeit it doesn't copy to the correct location. How do I solve this?
The following code works without any error.
Mat large_img = imread("C:\\Koala.jpg");
Mat small_img;
resize(large_img,small_img,Size(100,100),1);
small_img.copyTo(large_img (Rect(100,100,100,100)));
imshow("Rsult",large_img);
waitKey(0);
The small image is re-sized version of large image and it is copied in b/w (100,100) location to (200,200) in the large image. You can adopt these lines according to your requirement.
To paste a image scaledImage to resultMat:
scaledImage.copyTo(resultMat);
But i don't think you can select a roi in Java to copy at a particular region.