Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to identify contours within another contour using JavaCV?

How to identify contours within another contour? I tried to go through many OpenCV tutorials but I was unable to identify it. Please can some expert person provide simple code to explain it?

This is my input file

enter image description here

This dark part is the contour that I need to identify.

enter image description here

Please be kind enough to share your experience with me.

like image 742
NadLnk Avatar asked Jul 12 '12 14:07

NadLnk


2 Answers

Not very comfortable with JavaCV, so here's how I went about solving this problem in OpenCV and C (ancient stuff):

  1. Find all the contours in the image using the cvFindContours()
  2. Run two loops (iterate pointers h_next or whatever is there in JavaCV) over these contours. For each contour in the outer loop, match it with every other contour detected based on . . .
  3. Calculate bounding box of each contour. This will be a CvRect structure.
  4. Pass the two CvRects to a function that calculates the area of intersection (overlap) between two rectangles.
  5. If this area is equal to area of the smaller of the two rectangles, then the contour corresponding to the smaller rectangle is completely enclosed by the larger one.

    Here's the code for finding the area of intersection. It must have been floating around the web somewhere.

    CvRect intersect(CvRect r1, CvRect r2) { CvRect intersection;

    // find overlapping region
    intersection.x = (r1.x < r2.x) ? r2.x : r1.x;
    intersection.y = (r1.y < r2.y) ? r2.y : r1.y;
    intersection.width = (r1.x + r1.width < r2.x + r2.width) ?
        r1.x + r1.width : r2.x + r2.width;
    intersection.width -= intersection.x;
    intersection.height = (r1.y + r1.height < r2.y + r2.height) ?
        r1.y + r1.height : r2.y + r2.height;
    intersection.height -= intersection.y;    
    
    // check for non-overlapping regions
    if ((intersection.width <= 0) || (intersection.height <= 0)) {
        intersection = cvRect(0, 0, 0, 0);
    }
    
    return intersection;
    

    }

like image 153
AruniRC Avatar answered Nov 20 '22 14:11

AruniRC


Here is a simple approach in Python code. (But as I stated in my comment below, It is not an universal answer applicable everywhere, It is just to show finding contour inside a contour can be done. And if your images are different, then you have to come with some different constraints other than i mentioned below)

What you are doing after finding Contours is that, you check if area of each contour is less than a specified value ( i gave 10000, just a guess), if not it is bigger contour, avoid it. If less than specified value, it may be our square or rectangle next to it.

So we find its width and height and check if aspect ratio close to 1. if so, it is our square.

import cv2
import numpy as np

img = cv2.imread('sofcnt.jpg')
gray = cv2.imread('sofcnt.jpg',0)

ret,thresh = cv2.threshold(gray,127,255,1)

cont,hier = cv2.findContours(thresh,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)

for cnt in cont:
    approx = cv2.approxPolyDP(cnt,0.02*cv2.arcLength(cnt,True),True)
    if cv2.contourArea(cnt) < 10000:
        x,y,w,h = cv2.boundingRect(cnt)
        if w/float(h) < 2:
            cv2.drawContours(img,[cnt],0,255,-1)


cv2.imshow('a',img)
cv2.waitKey(0)
cv2.destroyAllWindows()

Result :

enter image description here

like image 22
Abid Rahman K Avatar answered Nov 20 '22 13:11

Abid Rahman K