am using the findContours() function to find a business card in an image, however sometimes the card is very small in the image. It still finds the card but when I go to do further processing on the image I get unexpected results from cards due to the inconsistency in size of the card.
How can I take outImg and ensure it is always of size x,y?
You can use cv:resize to do it. Unlike in the other answer, You provide a desired-size cv::Size structure and leave the scale factor arguments.
cv::resize(theSourceOfAllEvil,myAwesomeMatrixResized,cv::Size(width,heigth));
Related
Is that possible to get the depth/disparity map from a moving camera? Let say I capture an image at x location, after I travelled let say 5cm and I capture another picture, and from there I calculate the depth map of the image.
I have tried using BlockMatching in opencv but the result is not good.The first and second image are as following:
first image,second image,
disparity map (colour),disparity map
My code is as following:
GpuMat leftGPU;
GpuMat rightGPU;
leftGPU.upload(left);rightGPU.upload(right);
GpuMat disparityGPU;
GpuMat disparityGPU2;
Mat disparity;Mat disparity1,disparity2;
Ptr<cuda::StereoBM> stereo = createStereoBM(256,3);
stereo->setMinDisparity(-39);
stereo->setPreFilterCap(61);
stereo->setPreFilterSize(3);
stereo->setSpeckleRange(1);
stereo->setUniquenessRatio(0);
stereo->compute(leftGPU,rightGPU,disparityGPU);
drawColorDisp(disparityGPU, disparityGPU2,256);
disparityGPU.download(disparity);
disparityGPU2.download(disparity2);
imshow("display img",disparityGPU);
how can I improve upon this? From the colour disparity map, there are quite a lot error (ie. the tall circle is red in colour and it is the same as some of the part of the table.). Also,from the disparity map, there are small noise (all the black dots in the picture), how can I pad those black dots with nearby disparities?
It is possible if the object is static.
To properly do stereo matching, you first need to rectify your images! If you don't have calibrated cameras, you can do this from detected feature points. Also note that for cuda::StereoBM the minimum default disparity is 0. (I have never used cuda, but I don't think your setMinDisparity is doing anything, see this anser.)
Now, in your example images corresponding points are only about 1 row apart, therefore your disparity map actually doesn't look too bad. Maybe having a larger blockSize would already do in this special case.
Finally, your objects have very low texture, therefore the block matching algorithm can't detect much.
I'm using OpenCV 3.3.1. I want to do a semi-dense optical flow operation using cv::calcOpticalFlowPyrLK, but I've been getting some really noticeable slowdown whenever my ROI is pretty big (Partly due to the fact that I am letting the user decide what the winSize should be, ranging from from 10 to 100). Anyways, it seems like cv::buildOpticalFlowPyramid can mitigate the slowdown by building image pyramids? I'm sorta familiar what image pyramids are, but in context of the function, I'm especially confused about what parameters I pass in, and how it impacts my function call to cv::calcOpticalFlowPyrLK. With that in mind, I now have these set of questions:
The output is, according to the documentation, is an OutputArrayOfArrays, which I take it can be a vector of cv::Mat objects. If so, what do I pass in to cv::calcOpticalFlowPyrLK for prevImg and nextImg (assuming that I need to make image pyramids for both)?
According to the docs for cv::buildOpticalFlowPyramid, you need to pass in a winSize parameter in order to calculate required padding for pyramid levels. If so, do you pass in the same winSize value when you eventually call cv::calcOpticalFlowPyrLK?
What exactly are the arguments for pyrBorder and derivBorder doing?
Lastly, and apologies if it sounds newbish, but what is the purpose of this function? I always assumed that cv::calcOpticalFlowPyrLK internally builds the image pyramids. Is it just to speed up the optical flow operation?
I hope my questions were clear, I'm still very new to OpenCV, and computer vision, but this topic is very interesting.
Thank you for your time.
EDIT:
I used the function to see if my guess was correct, so far it has worked, but I've seen no noticeable speed up. Below is how I used it:
// Building pyramids
int maxLvl = 3;
maxLvl = cv::buildOpticalFlowPyramid(imgPrev, imPyr1, cv::Size(searchSize, searchSize), maxLvl, true);
maxLvl = cv::buildOpticalFlowPyramid(tmpImg, imPyr2, cv::Size(searchSize, searchSize), maxLvl, true);
// LK optical flow call
cv::calcOpticalFlowPyrLK(imPyr1, imPyr2, currentPoints, nextPts, status, err,
cv::Size(searchSize, searchSize), maxLvl, termCrit, 0, 0.00001);
So now I'm wondering what's the purpose of preparing the image pyramids if calcOpticalFlowPyrLK does it internally?
So the point of your question is that you are trying to improve speed of optical flow tracking by tuning your input parameters.
If you want dirty and quick answer then here it is
KTL (OpenCV's calcOpticalFlowPyrLK) define a e residual function which are sum of gradient of point inside search window .
The main purpose is to find vector of point that can minimize residual function
So if you increase search window size (winSize) then it is more difficult to find that set of points.
If your really really want to do that then please read the official paper.
See the section 2.4
http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.185.585&rep=rep1&type=pdf
I took it from official document
https://docs.opencv.org/2.4/modules/video/doc/motion_analysis_and_object_tracking.html#bouguet00
Hope that help
Is there a way to produce a glare on an image? Given an image with an object, I want to produce a glare on a portion of an image. If I have an image that is 256x256, I want to produce glare on the first 64x64 patch. Is there a function in opencv I can use for that? If not, what is a good way to go about this problem?
I think that this example does what you need. Each time it saves a face, it gives a flash in the part of the screen where the face was recognised. So, the glares changes every time of place and size.
You can found it here:
https://github.com/MasteringOpenCV/code/tree/master/Chapter8_FaceRecognition
Seek this part in the main.cpp:
// Make a white flash on the face, so the user knows a photo has been taken.
Mat displayedFaceRegion = displayedFrame(faceRect);
displayedFaceRegion += CV_RGB(90,90,90);
I'm having a weird behaviour using srcset and I'm having a hard time understanding it. I've done a CodePen: http://codepen.io/anon/pen/dYBvNM
The problem is that I have a set of images (that Shopify generates) of various sizes: 240px, 480px, 600px and 1024px. The problem is that those are the maximum sizes. This means that if a merchant uploads a smaller image (let's say 600px), the 1024px version will be 600px, not 1024px. I cannot know that in advance, so I'm forced to simply add all the sizes as a "best case":
<img
src="my_1024x1024.jpg"
srcset="my_240px.jpg 240w, my_480px.jpg 480w, my_600px.jpg 600w, my_1024px 1024w"
sizes="(max-width: 35em) 100vh, 610px"
>
The weirdness happen when the image is indeed smaller than the expected max size. When that the case, the browser correctly select the appropriate image (in this case, it would select the 1024 version on a 15' Retina), but as the image is actually smaller than 1024px (size that I've indicated), the browser is actually resizing the image to be smaller than its native resolution.
You can compare in the CodePen http://codepen.io/anon/pen/dYBvNM that those two images are the 1024px version, but in the one using srcset, the rendering is actually smaller than with src only. I would have expected that it would leave the image at its native resolution.
Could you please explain why does that?
THanks!
The way it works is that 'w' descriptors are calculated into 'x' descriptors by dividing the given value with the effective size from the sizes attribute. So for instance, if 1024w is picked and the size is 610px, then 1024/610 = 1.67868852459016x, and that is the pixel density of the image that the browser will apply. If the image is then not in fact 1024 pixels wide, the browser will still apply this same density, which will "shrink" the image, because that's the right thing to do in the valid case when the image width and 'w' descriptor match.
You have to make the descriptors match the resource width. When the user uploads an image, you can check its width and use that as the biggest descriptor in sizes (if it's smaller than 1024), and remove the descriptors that are bigger than the given image width.
After doing some opencv operation, I initialize a new image that I'd like to use. Saving this empty image gives a weird result
The lines I use to save this image are:
Mat dst2 (Size (320, 240), CV_8UC3);
imwrite("bla.jpg", dst2);
I should get a black image, but this is what I get. Moving these two lines to the start of the program everything wordks fine
Anyone had this problem before?
I just noticed that these white lines contain portions from other images I'm processing in the same program
Regards
Because you did not initialize the image with any values, you just defined the size and type, you will get random pixels (or not so random, it is probably showing pieces of pixels in memory).
It is the same concept of using/accessing an uninitialized variable.
To paint the image black you can use Mat::setTo, docs here:
http://docs.opencv.org/modules/core/doc/basic_structures.html#mat-setto