I have the following images:
result:
but it can be managed with area check with some pre determined values
CodePudding user response:
Here is one approach using Python/OpenCV. Basically, remove the horizontal and vertical lines. Then get and filter contours on area.
Input:
import cv2
import numpy as np
# read image
img = cv2.imread('notes.png')
# convert to grayscale
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# threshold
thresh = cv2.threshold(gray,128,255,cv2.THRESH_BINARY)[1]
# do morphology remove horizontal lines
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1,5))
lines1 = cv2.morphologyEx(gray, cv2.MORPH_CLOSE, kernel, iterations = 1)
# do morphology to remove vertical lines
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,1))
lines2 = cv2.morphologyEx(lines1, cv2.MORPH_CLOSE, kernel, iterations = 1)
lines2 = cv2.threshold(lines2,128,255,cv2.THRESH_BINARY)[1]
# invert lines2
lines2 = 255 - lines2
# get contours
cntrs = cv2.findContours(lines2, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cntrs = cntrs[0] if len(cntrs) == 2 else cntrs[1]
# filter contours on area and draw good ones as black filled on white background
result = np.full_like(img, (255,255,255))
for cntr in cntrs:
area = cv2.contourArea(cntr)
if area > 9 and area < 400:
# get centroid
M = cv2.moments(cntr)
cx = M["m10"] / M["m00"]
cy = M["m01"] / M["m00"]
pt="(" str(cx) "," str(cy) ")"
print("area:",area,"center:",pt)
cv2.drawContours(result, [cntr], 0, (0,0,0), -1)
# write result to disk
cv2.imwrite("notes_lines_removed.png", result)
# display it
cv2.imshow("lines1", lines1)
cv2.imshow("lines2", lines2)
cv2.imshow("result", result)
cv2.waitKey(0)
Result:
area: 360.0 center: (12.710648148148147,19.85972222222222)
area: 309.0 center: (64.38619201725997,10.55393743257821)