How to form boxes from nearly touching lines

2024/11/20 17:29:26

enter image description hereI want to detect corners from a image with boxes, although i created the chessboard edge lines with the EDlines algorithm. Now, I have some problems to join them to create perfect boxes. Could you help me maybe?

ed_anti=cvX.createEdgeDrawing()ed_anti.detectEdges(binarized)edges_anti=ed_anti.getEdgeImage(None)segments_anti=ed_anti.getSegments()#gets the segments of the edgesgradiant_anti=ed_anti.getGradientImage(None)#detects the gradient of the edgesed_lines_anti=ed_anti.detectLines(None)#detects the linesif ed_lines_anti is not None: lines_anti = np.uint16(np.around(ed_lines_anti))for i in range(len(ed_lines_anti)):cv.line(anti_black_image, (lines_anti[i][0][0], lines_anti[i][0][1]), (lines_anti[i][0][2], lines_anti[i][0][3]), (250, 0, 250), 1, cv.LINE_AA)

enter image description here

Answer

Here is one approach in Python/OpenCV to get your boxes.

 - Read the image- Convert to grayscale- Threshold and invert (to find the original black boxes)- Pad with white all around- Floodfill with black to turn the white corners to black.- Crop the padding away- Apply close morphology to fill in black specks- Apply erode morphology to separate the cells- Get external contours for the cells- Draw red contours on a black image- Draw red contours on a copy of the input- Save the results

Input:

enter image description here

import cv2
import numpy as np# read the input
img = cv2.imread('checkerboard.png')# convert to grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# threshold and invert
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)[1]# add white border and floodfill the border to black
pad = cv2.copyMakeBorder(thresh, 10,10,10,10, cv2.BORDER_CONSTANT, value=(255))
hh, ww = pad.shape
mask = np.zeros([hh + 2, ww + 2], np.uint8)
floodfill = cv2.floodFill(pad, mask, (0,0), (0), (0), (0), flags=4)[1]
hh, ww = floodfill.shape# crop padding
crop = floodfill[10:hh-10, 10:ww-10]# apply morphology to remove small spots and then disconnect cells
kernel = np.ones((3,3), np.uint8)
clean = cv2.morphologyEx(crop, cv2.MORPH_CLOSE, kernel)
kernel = np.ones((9,9), np.uint8)
clean = cv2.morphologyEx(clean, cv2.MORPH_ERODE, kernel)# get contours
cntr_img = np.zeros_like(clean)
cntr_img = cv2.merge([cntr_img,cntr_img,cntr_img])
cntr_img2 = img.copy()
contours = cv2.findContours(clean, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]
for cntr in contours:area = cv2.contourArea(cntr)if area > 10:cv2.drawContours(cntr_img, [cntr], -1, (0,0,255), 1)cv2.drawContours(cntr_img2, [cntr], -1, (0,0,255), 1)# save results
cv2.imwrite('checkerboard_thresh.jpg', thresh)
cv2.imwrite('checkerboard_floodfill.jpg', floodfill)
cv2.imwrite('checkerboard_crop.jpg', crop)
cv2.imwrite('checkerboard_contours.jpg', cntr_img)
cv2.imwrite('checkerboard_contours2.jpg', cntr_img2)# show the results
cv2.imshow('threshold', thresh)
cv2.imshow('floodfill', floodfill)
cv2.imshow('crop', crop)
cv2.imshow('clean', clean)
cv2.imshow('cntr_img', cntr_img)
cv2.imshow('cntr_img2', cntr_img2)
cv2.waitKey(0)

Threshold and inverted image:

enter image description here

Floodfilled image:

enter image description here

Cropped image (crop to remove added padding):

enter image description here

Contours on black background:

enter image description here

Contours on copy of input:

enter image description here

https://en.xdnf.cn/q/119804.html

Related Q&A

How to change app.py variable with HTML button?

How do I add or subtract 1 from the variable num ( in flask route) with an HTML button? So when I click the button it change the var to 1 and refresh the page to show the new value @app.route(/) def n…

How to check if time is in the range between two days?

I found some nice examples to check, if a time is in a specific range, like this one:now_time = datetime.datetime.now().time() start = datetime.time(17, 30) end = datetime.time(4, 00) if start <=…

Removing Duplicate Domain URLs From the Text File Using Bash

Text file https://www.google.com/1/ https://www.google.com/2/ https://www.google.com https://www.bing.com https://www.bing.com/2/ https://www.bing.com/3/Expected Output: https://www.google.com/1/ https…

How can I create a race circuit using Cubic Spline?

My problem is im using Cubic Spline but i get this error trying to graph a race circuit raise ValueError("x must be strictly increasing sequence.") ValueError: x must be strictly increasing s…

Why cant python find my module?

Im getting this error every time I type python manage.py runserver in the root server of my Django app. ImportError: No module named utilsI just added a new app to my project called utils by running py…

Seperating the numbers from strings to do the maths and return the string with the results [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.Want to improve this question? Update the question so it focuses on one problem only by editing this post.Closed 4…

Protect an API by using OAuth 2.0 with Azure Active Directory and API Management

I want to Protect amy API by using OAuth 2.0 with Azure Active Directory and API Management. I have added my API in API management and Im following this article https://learn.microsoft.com/en-in/azure…

How can filter by list in django

I am trying to filter a queryset by a list I am getting unicode data into format of 1,4,5,6 bycategory = request.GET.getlist(category) print type(category)data = Leads.objects.filter(item_required__id…

Python: get the return code of ant sub-process in windows

I use python to call ant, I want to get the return code of the ant for detect ant error.for example, in cmd.exe, C:\Documents and Settings\Administrator>ant sfsf Buildfile: build.xml does not exist!…

Skipp the error while scraping a list of urls form a csv

I managed to scrape a list of urls from a CSV file, but I got a problem, the scraping stops when it hits a broken link. Also it prints a lot of None lines, is it possible to get rid of them ? Would ap…