Reputation: 25
I need to find boxes in the following images using opencv
. I have tried using mser but i am not getting any good results.
My code for MSER:
mser = cv2.MSER_create()
img = cv2.imread('Lines.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
I = img.copy()
regions, _ = mser.detectRegions(I)
hulls = [cv2.convexHull(p.reshape(-1, 1, 2)) for p in regions]
mask = np.zeros((img.shape[0], img.shape[1], 1), dtype=np.uint8)
c=0
points=[]
for contour in hulls:
[x, y, w, h] = cv2.boundingRect(contour)
if w < 50 or h < 8 or w>120:
continue
c=c+1
cv2.rectangle(I, (x, y), (x + w, y + h), (255, 0, 255), 0)
plt.figure(1,figsize=(100, 50))
plt.imshow(I)
Result for MSER:
Upvotes: 1
Views: 6271
Reputation: 31
I think you can use pixel patterns to identify boxes. As the example go through the each pixel in image and when you get an white pixel then findout the next pixel colour in x axis and y axis. if both are white then consider that pixel as the first pixel of box. then take next pixel of x axis and find the y axis pixel. if it is white then you have reach to the other corner of box. if pixel is not white then consider next x axis pixel. when you are in corner then find the next y axis pixel until you reach the corner. when you are in third corner consider the previous x pixel. then find previous x pixel until you reach the fourth corner. then you can save the box by pixel coordinates of four corners. I think this is more accurate. But it is time consuming and complex. but it may be new algorithm. (this is only valid if boxes are direct lines)
Upvotes: 0
Reputation: 2831
You could threshold your image and invert your white and black pixels so your boxes are white seperated with black lines:
Then you can search for your contours with cv2.findContours()
and then draw only the ones that fit your size criteria. You can get the size of the contour with cv2.contourArea()
. Those contours are your boxes. Cheers!
Sample code:
import cv2
img = cv2.imread('table.png')
resize = cv2.resize(img, None, fx=0.3, fy=0.3, interpolation = cv2.INTER_CUBIC)
gray = cv2.cvtColor(resize, cv2.COLOR_BGR2GRAY)
_,thresh = cv2.threshold(gray,50,255,cv2.THRESH_BINARY_INV)
_, contours, _ = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
for cnt in contours:
size = cv2.contourArea(cnt)
if 100 < size < 30000:
cv2.drawContours(resize, [cnt], 0, (0,255,0), 1)
cv2.imshow('img', resize)
Result:
Upvotes: 4
Reputation: 26
Since your input image is inverted, use 'dilate' with a suitable structuring element to enlarge the extremal regions and then apply MSER.
Upvotes: 1