I use ExtractBiggestBlob to minimize my original image to smallest possible contour. And I do this only after binarize the original Image so that I can get smallest possible contour of my image. How can I find the coordinates of the blob after using ExtractBiggestBlob so that I can use that to crop from the original image?
EDIT 1:
I have found it out:
ExtractBiggestBlob BBB = new ExtractBiggestBlob();// Extract the biggest Blob
Bitmap biggestBlobsImage = BBB.Apply(ChannelImage);
IntPoint blobPosition = BBB.BlobPosition;
//Console.WriteLine(blobPosition.X);
//Console.WriteLine(blobPosition.Y);
Related
Can I compare a pixel from the original image to another same coordinate pixel from a colored image to check what is the color of the pixel from the colored image to the original image? Is there a way to do that?
You can take the absolute difference between them. The result will be the difference of each pixel.
cv::Mat first,second,result;
//first= some image
//second =other image
cv::absdiff(first,second,result);
EDIT:
By the previous step, you have got the difference map. You can simply now do this:
auto some_pixle_difference=result.at<vec3b>(cv::Point(x,y));
some_pixle_difference will contain the differences between pixel x,y from both images.
I want to find local maxima of each '3X3' sized Window. So, How do we find that local maxima of each 3X3 sized Window in an image in OpenCV ?
You can use morphological operation dilate:
Mat img; // your input image that you should fill with values
Mat maxims(img.size(), img.type()); // container for all local maximums
dilate(img, maxims, Mat());
As a result each pixel of 'maxims' is maximum of appropriate 3x3 window in 'img'. Read more about morphological operation (dilatation, erosion, close, open, etc...) on Wikipedia or somewhere else.
Please see my answer to Find local maxima in grayscale image using OpenCV
The idea is to dilate with a kernel that has a "hole" in the middle (i.e. replace each pixel with the maximum of all its neighbors, excluding the pixel itself), and then compare the result to the original image.
I am new to OpenCV and I was trying to extract the region bound by largest contour. It may be a simple question, but I am not able to figure it out. I tried googling too, without any luck.
I would:
Use contourArea() to find the largest closed contour.
Use boundingRect() to get the bounds of that contour.
Draw the contour using drawContours() (with thickness set to -1 to
fill the contour) and use this as a mask.
Use use the mask to set all pixels in the original image not in the
ROI to (0,0,0).
Use the bounding rectangle to extract just that area from the
original image.
Here is well explained what do you want do develop.
Basically you have to:
apply threshold to a copy of the original image;
use findContours -> output is:
vector<vector<Point>>
that stores contours;
iterate on contours to find the largest.
It is possible obtain only 5 objects (one per sign) by applying find_contour (opencv module) in this image: https://docs.google.com/file/d/0ByS6Z5WRz-h2WHEzNnJucDlRR2s/edit ?
Now I obtain 64 objects
After that I want to retrieve Humoments and make a comparison with other images.
For now i'd try only with the same image a little bit translated, for testing it returns they are the same.
My question I how can I obtain only 5 objects for applying humoments or if there are other solutions to calculate humoments fot the image?
import cv2
im = cv2.imread('Sassatelli 1984 n. 165 mod1.jpg')
imgray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(imgray, (0,0), 5)
cv2.imshow('Blur', blur)
cv2.waitKey()
th = 20
edges = cv2.Canny(blur, th, th*3)
cv2.imshow('canny',edges)
cv2.waitKey()
contours, hierarchy = cv2.findContours(edges, cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
print('objects found')
print(len(contours))
cnt = contours[0]
cv2.drawContours(blur,contours,-1,(0,255,0),3)
cv2.imshow('draw contours',blur)
cv2.waitKey()
moments = cv2.moments(cnt)
Case 1: Problem with saving image in jpg format
When you save a black-and-white-only (ie pixel values 0 and 255 only) image in jpg format, there is lossy compression, which changes the pixel values. If you want to see it, create such an image, save it in jpg, open the saved image and zoom to black-white edge. You can see a pixel value change.
So when you find contours, you expect there is only white objects, but in reality, there is some mid-values also, which is also considered as contours. It increases number of contours.
So to avoid this problem,
Better save images in png or any other lossless format etc.
Apply a threshold, (with a values of 127 or as you like) to make image real binary one before finding contours.
This is much more explained here : What does result of 'list(contour)' denote?
Case 2: Problem with white background
OpenCV findcontours() is designed to find white objects in black background. So if your background is white, it is also treated as one object. So invert the image before finding contours.
Case 3 : Problem with holes in objects
If you have holes in your object, it is also considered as an object. So if you want only external boundary of the objects, use cv2.RETR_EXTERNAL flag for findcontours() function.
Sample Code:
import cv2
import numpy as np
img = cv2.imread('sof.jpg')
gray = cv2.imread('sof.jpg',0)
ret,thresh = cv2.threshold(gray,127,255,cv2.THRESH_BINARY_INV)
thresholded and inverted image :
Now find the contours, draw it, check the number of contours:
cv2.drawContours(img,contours,-1,(0,255,0),2)
cv2.imshow('img',img),cv2.waitKey(0),cv2.destroyAllWindows()
Result :
NOTE :
Here, I have taken only external contours. If you want to remove internal holes from these objects, you will need to use cv2.RETR_TREE or cv2.RETR_CCOMP flags, and check their hierarchy, and remove them. It is explained in this link : Contours 5 : Hierarchy
If I have an RGB image and a binary mask (1 channel), and I want to create contours for the RGB image based on the connected pixels of the binary mask. After that I want to compare the pixel values (e.g. check if each pixel in the contours is having a blue value > 150), then how can I implement the above by using OpenCV?
Thanks a lot!
Assuming the images are the same size and shape then simply scan over the pixels in the binary image looking for the contours and check the pixel values at the same row/col in the color image
See Fastest way to extract individual pixel data? for details