How can I find the area and perimeter of objects detected using sobel edge detection algorithm? Did not find any soution
Sobel operator is a filter kernel. After convolution of an image with that kernel you get an approximation of the image's first derivative. It can be used to get gradient information. Its most common application is edge detection.
Sobel is no object detection algorithm. Hence it cannot give you perimeter or area of any object. You need further intermediate steps.
To choose an algorithm that suits your needs one would have to know your image. Otherwise no useful answer can be provided.
If you have a simple binary image google for blob detection or labeling.
To get objects in the first place google for image segmentation.
Related
I want to use OpenCv methods to segment images.I have come across Grabcut algorithm but this still requires human interaction like drawing a box to circle a object.
So my question is how to I use OpenCv to do segmentation automatically? Suggestions and code snippet in either C++ or Java are much appreciated.
UPDATE: I'm trying to segment food items from plate and table.
Yes, grabCut requires human interaction, But we can minimize it, like I have personally used grabCut algorithm for segmenting faces from the given image, So it basically involves:
Detecting face in the given image using haar cascade
Generating a probability mask, which would help you in generating markers required for the segmentation.
The first part requires you to either use a pre-manufactured haar cascade, or create your own by providing sufficient training examples.
Once you have a working haar cascade, you can use it to get ROI for each input image, You may extend the ROI dimensions to include more space around the object.
So Now at this step you must be able to crop your required object from the given input image, which reduces the search domain, Now you can create a probability mask, which would indicate the probable location of object for a given ROI, the previous steps were necessary to normalize the input image, Now we can assume the input is always normalized so the object location would be somewhat consistent w.r.t ROI. Here is a sample probability mask for male Human hair:
Now you choose 4 thresholds to create mask for grabcut as:
if (pix > 220): mask = cv::GC_FGD
else if (pix > 170): mask = cv::GC_PR_FGD
else if (pix > 50): mask = cv::GC_PR_BGD
else: mask = cv::GC_BGD
Then you can pass this as mask to perform grabcut segmentation.
However there has been some recent advancements in semantic segmentation, which uses CRF as RNN technique to segment objects form the given image, it requires no normalization thing, but due to it's dependency on GPU for efficient running, it is not suitable for mobile or low end computer applications.
I have some conceptual issues in understanding SURF and SIFT algorithm All about SURF. As far as my understanding goes SURF finds Laplacian of Gaussians and SIFT operates on difference of Gaussians. It then constructs a 64-variable vector around it to extract the features. I have applied this CODE.
(Q1 ) So, what forms the features?
(Q2) We initialize the algorithm using SurfFeatureDetector detector(500). So, does this means that the size of the feature space is 500?
(Q3) The output of SURF Good_Matches gives matches between Keypoint1 and Keypoint2 and by tuning the number of matches we can conclude that if the object has been found/detected or not. What is meant by KeyPoints ? Do these store the features ?
(Q4) I need to do object recognition application. In the code, it appears that the algorithm can recognize the book. So, it can be applied for object recognition. I was under the impression that SURF can be used to differentiate objects based on color and shape. But, SURF and SIFT find the corner edge detection, so there is no point in using color images as training samples since they will be converted to gray scale. There is no option of using colors or HSV in these algorithms, unless I compute the keypoints for each channel separately, which is a different area of research (Evaluating Color Descriptors for Object and Scene Recognition).
So, how can I detect and recognize objects based on their color, shape? I think I can use SURF for differentiating objects based on their shape. Say, for instance I have a 2 books and a bottle. I need to only recognize a single book out of the entire objects. But, as soon as there are other similar shaped objects in the scene, SURF gives lots of false positives. I shall appreciate suggestions on what methods to apply for my application.
The local maxima (response of the DoG which is greater (smaller) than responses of the neighbour pixels about the point, upper and lover image in pyramid -- 3x3x3 neighbourhood) forms the coordinates of the feature (circle) center. The radius of the circle is level of the pyramid.
It is Hessian threshold. It means that you would take only maximas (see 1) with values bigger than threshold. Bigger threshold lead to the less number of features, but stability of features is better and visa versa.
Keypoint == feature. In OpenCV Keypoint is the structure to store features.
No, SURF is good for comparison of the textured objects but not for shape and color. For the shape I recommend to use MSER (but not OpenCV one), Canny edge detector, not local features. This presentation might be useful
in my project I want to crop the ROI of an image. For this I create a map with the regions of interesst. Now I want to crop the area which has the most important pixels (black is not important, white is important).
Has someone an idea how to realize it? I think this is a maximazion problem
The red border in the image below is an example how I want to crop this image
If I understood your question correctly, you have computed a value at every point in the image. These values suggests the "importance"/"interestingness"/"saliency" of each point. The matrix/image containing these values is the "map" you are referring to. Your goal is to get the bounding box for regions of interests (ROI) with high "importance" score.
The way I think you can go about segmenting the ROIs is to apply Graph Cut based segmentation computing a "score" at each pixel using your importance map. The result of the segmentation is a binary mask that masks the "important" pixels. Next, run OpenCV's findcontours function on this binary mask to get the individual connected components. Then use OpenCV's boundingRect function on the contours returned by findContours(...) to get the bounding boxes.
The good thing about using a Graph Cut based segmentation algorithm in this way is that it will join up fragmented components i.e. the resulting binary mask will tend not to have pockets of small holes even if your "importance" map is noisy.
One Graph Cut based segmentation algorithm already implemented in OpenCV is the GrabCut algorithm. A quick hack would be to apply it on your "importance" map to get the binary mask I mentioned above. A more sophisticated approach would be to build the foreground and background (color perhaps?) model using your "importance" map and passing it as input to the function. More details on GrabCut in OpenCV can be found here: http://docs.opencv.org/modules/imgproc/doc/miscellaneous_transformations.html?highlight=grabcut#void grabCut(InputArray img, InputOutputArray mask, Rect rect, InputOutputArray bgdModel, InputOutputArray fgdModel, int iterCount, int mode)
If you would like greater flexibility, you can hack your own graphcut based segmentation algorithm using the following MRF library. This library allows you to specify your custom objective function in computing the graph cut: http://vision.middlebury.edu/MRF/code/
To use the MRF library, you will need to specify the "cost" at each point in your image indicating whether that point is "foreground" or "background". You can also think of this dichotomy as "important" or "not important" instead of "foreground" vs "background".
The MRF library's goal is to return you a label at each point such that total cost of assigning those labels is as small as possible. Hence, the game is to come up with a function to compute a small cost for points you consider important and large otherwise.
Specifically, the cost at each point is composed of 2 parts: 1) The data term/function and 2) The smoothness term/function. As mentioned earlier, the smaller the data term at each point, the more likely that point will be selected. If your "importance" score s_ij is in the range [0, 1], then a common way to compute your data term would be -log(s_ij).
The smoothness terms is a way to suggest whether 2 neighboring pixels p, q, should have the same label i.e. both "foreground", "background", or one "foreground" and the other "background". Similar to the data cost, you have to construct it such that the cost is small for neighbor pixels having similar "importance" score so that they will be assigned the same label. This term is responsible for "smoothing" the resulting mask so that you will not have pixels of low "importance" sprinkled within regions of high "importance" and vice versa. If there are such regions, OpenCV's findContours(...) function mentioned above will return contours for these regions, which can be filtered out perhaps by checking their size.
Details on functions to compute the cost can be found in the GrabCut paper: GrabCut
This blog post provides a bit more detail (and code) on creating your own graphcut segmentation algorithm in OpenCV: http://www.morethantechnical.com/2010/05/05/bust-out-your-own-graphcut-based-image-segmentation-with-opencv-w-code/
Another paper showing how to perform graph cut segmentation on grayscale images (your case), with better notations, and without the complicated image matting part (not implemented in OpenCV's version) in the GrabCut paper is this: Graph Cuts and Efficient N-D Image Segmentation
Hope this helps.
I am working on an image registration method applied to histological images.
I have one question. I would like to use MSER feature detector to detect keypoints on my image. After the MSER contours were retrieved using the MSER function provided by opencv, I calculate the centroid of each contour in order to use it as an interesting point.
If I make a description of the interesting points directly, with a Surf descriptor for example, the size of the descriptor is one, and is not possible to compare them.
Therefore it is necessary to modify the size of the descriptor with a suitable size.
Does anyone have an idea?
Thanks
Tha answer is very late but I hope it helps someone.
MSER returns you regions and not points.
In order to extract descriptors from MSER regions, you have to map the regions to a standard size, say from any elliptical shape to 30x30 pixel circle and then extract descriptor (such as SURF) out of it.
If you use SURF alone then it uses Harris corners as interest points and then places fixed sized windows around it in a scale space.
Matching is done by comparing descriptors usually. You are trying to match keypoints (or interest points) which is different.
Last but not the least, it is unlikely that MSER centroids and SURF interest points can be can occur at the same location since MSER detect homogenous regions and SURF uses Harris Corners. Centroids of MSER can not have corners, so technically speaking, they will always be the outliers for each other.
In MATLAB 2011 onwards, MSER can be combined with SURF descriptors (Included in the Computer Vision System ToolBox).
One other way is to use computer_descriptors.ln shared by: http://www.robots.ox.ac.uk/~vgg/research/affine/descriptors.html
Best Regards
I don't need a working solution but I'm looking for somebody who can push me into the right direction with some useful hints/links:
I have an image with a fiducial in it (can be e.g. a cross or dot or whatever simple geometry). The images source itself is lit in a way so that a human would not like the resulting image but the contrast for the fiducial is very good. Next I have a clear geometric description of that fiducial (vector data format) and a nominal position of it.
Now I want OpenCV to find the fiducial into the image and return me its real, current position (and rotation for fiducials where this is possible).
How can this be done with OpenCV? The tutorials I found always use complex patterns like faces and pictures that are not optimised for the fiducial detection itself, therefore they all use very complicated learning/description methods.
Depending on your fiducial you can use different methods. A very common method, already implemented in OpenCV is SIFT, which finds scale invariant robust points in an image. The way to proceed is:
Run SIFT on your fiducial offline. This generates keypoints to be tracked.
Run SIFT real-time (or FAST, which can also generate SIFT descriptors) to find keypoints in the scene.
Use a matcher (FLANN matcher, for example) to find which keypoints found in the image correspong to the fiducial.
Run findhomography() for matched points. From the found homography H matrix 3x3, you can obtain the camera pose.
There are more aproaches, this the one I like and it is quite up-to-day and fast.