Confusion on cvSplit function - opencv

what is the proper way of using cvSplit function? I saw different version of it.
should it be
cvSplit(oriImg, r,g,b, NULL);
or
cvSplit(oriImg, b,g,r, NULL);

Both of them are ok, it depends on the channel ordering. By default OpenCV uses BGR, so in this case it would be cvSplit(oriImg, b,g,r, NULL);, but you can convert it to RGB and then use the other one.

It is exactly the same thing I was puzzled by when I started using OpenCV. OpenCV uses BGR instead of RGB so you should use
cvSplit(img,b,g,r,NULL);

Related

EmguCV 3.0.0 - CvInvoke.cvConvert equivalent

I want to convert between Matrix and Image in EmguCV 3.0.0.
I saw in this video (https://www.youtube.com/watch?v=DfTS5a9xmwo) that you can do this with the CvInvoke.cvConvert method. But it seems this method doesn't exist anymore in EmguCV 3.0.0. I did find the method CVInvoke.ConvertMaps , but this method requires two input and two output arrays. Is this method equivalent if I use empty arrays as the second arrays?
Try the (.ToImage) method. It operates to convert to a Matrix to an image. a working example in C# is:
Image<Bgr,Byte> img1 = imgMat.ToImage<Bgr, Byte>();
You can also change it to a grayscale by using (gray,byte)
You can also find an example in VB at (http://www.emgu.com/forum/viewtopic.php?t=5209).

how to convert List<MatofPoint> to Mat in opencv?

Recently I'm developing android app using OpenCV. Now I encounter a problem:
Imgproc.findContours(grayMat, contours1, new Mat(), Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);
After this function, I want to call Imgproc.MatchShapes to detect whether 2 images are matched. but under Java edition MatchShapes requires parameters of type Mat.
How can I convert List<MatOfPoint> to Mat?
The function you use to detect contours returns a list of MatOfPoints. Each contour - because there can be many - has its own MatOfPoints.
You have to find a way to choose which contour you want to use with Imgproc.MatchShapes. If you know there's only one, then just use the first entry in the List<MatOfPoints>. If you want the biggest one, use some contour properties to find the biggest contour. If you have time, you can check every single contour.
Then, once you've found the single contour you want to compare, you can use that MatOfPoints. According to this StackOverflow question, they are perfectly compatible.

fast conversion of IplImage to Numpy array

The newer OpenCV documentation here says you can convert an IplImage to a Numpy array just like this:
arr = numpy.asarray( im )
but that doesn't work for my needs, because it apparently doesn't support math:
x = arr/0.01
TypeError: unsupported operand type(s) for /: 'cv2.cv.iplimage' and 'float'
If I try to specify data type, I can't even get that far:
arr = numpy.asarray( im, dtype=num.float32 )
TypeError: float() argument must be a string or a number
So I'm using the code provided in the older documentation here. Basically, it does this:
arr = numpy.fromstring( im.tostring(), dtype=numpy.float32 )
But the tostring call is really slow, perhaps because it's copying the data? I need this conversion to be really fast and not copy any buffers it doesn't need to. I don't think the data are inherently incompatible; I'm creating my IplImage with cv.fromarray in the first place, which is extremely fast and accepted by the OpenCV functions.
Is there a way I can make the newer asarray method work for me, or else can I get direct access to the data pointer in the IplImage in a way that numpy.fromstring will accept it? I'm using OpenCV 2.3.1 prepackaged for Ubuntu Precise.
Fun Fact:
Say you call:
import cv2.cv as cv #Just a formality!
Capture = cv.CaptureFromCAM(0)
Img = cv.QueryFrame(Capture)
The object Img is an ipimage, and numpy.asarray(Img) is erratic at best. However! Img[:,:] is a cvmat type, and numpy.asarray(Img[:,:]) works fantastically, and more important: quickly!
This is by far the fastest way I've found to grab a frame and make it an ndarray for numpy processing.
That page does not say about IplImage. It says about CvMat which is different.
Anyway you'd better use wrappers from newer cv2 namespace. It natively uses numpy arrays instead of own image containers. Also the whole cv module is considered deprecated and will be completely dropped in the nearest major release.

How to get depth and channel for a cvMat?

I am convert a numpy array to a cvMat using fromArray() function. Now when I try to apply Threshold on it I get the below error
OpenCV Error: Unsupported format or combination of formats () in threshold
On checking on stackoverflow I see that it might be an issue with the channel or depth of my image. But I am not sure how can I check that for a cvMat. Could somebody tell me how to check the depth and number of channels for a cvMat in python.
Well, you can't directly get it from a cvMat because cvMats have types instead of depth/channels, so
print mymat.type
returns the type code.
If you want to get the depth and channel number, the easiest way I've found is to generate the IplImage header with cv.GetImage like
print cv.GetImage(mymat).depth,cv.GetImage(mymat).nChannels
I believe cv2 does away with all of that IplImage/cvMat stuff and rolls it all into Mat though.

Converting IplImage to osg::Image

How can I correctly convert an OpenCV IplImage to OpenSceneGraph's osg::Image?
This my current method. But I'm getting incorrect color data.
// IplImage* cvImg is a webcam output image captured using cvQueryFrame(capture)
osg::ref_ptr<osg::Image> osgImage = new osg::Image;
osgImage->setImage(cvImg->width,cvImg->height, 3,
GL_RGB, GL_RGB, GL_UNSIGNED_BYTE,
(BYTE*)(cvImg->imageData),
osg::Image::AllocationMode::NO_DELETE,1);
This is likely an issue involving OpenCV's native BGR color space. You don't mention which version of OpenCV you are using, but modern versions define CV_BGR2RGB for use with cvCvtColor. Possibly doing the conversion like this
IplImage* pImg = cvLoadImage("lines.jpg", CV_LOAD_IMAGE_COLOR);
cvCvtColor(pImg, pImg, CV_BGR2RGB);
cvReleaseImage(&pImg);
If you can't use that another option would be use cvSplit to separate and reorder the channels and then combine them with cvMerge.
On a side note, I would definitely recommend using the C++ interface as it is much easier memory management, and has more features than the C interface.
Hope that helps!

Resources