3 回答
TA贡献1712条经验 获得超3个赞
我不知道这种方法是否适用于您的所有图像,但我注意到您想要删除网格的所有位置都有白线,并且图像的所有其余部分都是黑色的,因此它们似乎是一个有用的地方处理的目标。
我使用ImageMagick,但该方法可以轻松转换为 OpenCV。因此,步骤如下:
克隆图像和阈值,使浅色线条变为白色,其余线条变为黑色
将白色区域扩大为 3 个正方形,这样白线就会扩大以覆盖附近的黑色网格
将白色替换为灰色(171)以匹配您的背景
使黑色透明
将结果合成到原始图像上,以用灰色隐藏白线和附近的黑色区域
magick sudoku.png \( +clone -threshold 80% -fill "gray(171)" -morphology dilate square:3 -opaque white -transparent black \) -composite result.png
TA贡献1780条经验 获得超1个赞
检测线路,使用
fastLineDetector
设置长度阈值
绘制与背景相同的线条。
输出:
代码:
import cv2
gray = cv2.imread("gray.png", cv2.IMREAD_GRAYSCALE)
lines = cv2.ximgproc.createFastLineDetector(_length_threshold=15).detect(gray)
if lines is not None:
for line in lines:
(x_start, y_start, x_end, y_end) = line[0]
cv2.line(gray, (x_start, y_start), (x_end, y_end), (172, 172, 172), thickness=4)
cv2.imwrite("gray_result.png", gray)
cv2.imshow("result", gray)
cv2.waitKey(0)
cv2.destroyAllWindows()
我们首先检查是否检测到这些行:
if lines is not None:
如果检测到线条,则获取坐标:
(x_start, y_start, x_end, y_end) = line[0]
然后画线:
cv2.line(gray, (x_start, y_start), (x_end, y_end), (172, 172, 172), thickness=4)
您可以更改线条的粗细,例如,如果将粗细设置为 10。
cv2.line(gray, (x_start, y_start), (x_end, y_end), (172, 172, 172), thickness=10)
输出:
TA贡献1817条经验 获得超6个赞
有多种方法可以完成此类任务。除了其他答案之外,我还制作了另外两个示例来说明如何使用 numpy 和 OpenCV 来实现这一目标。选择正确的方式与您希望用什么来替换网格有关。
方法1:使用cv2.inpaint()函数方法2:找到白色像素并将其绘制出来
# imports
import cv2
import numpy as np
img = cv2.imread("sudoku.png") # read image
color = img[3, 3] # color of pixel in (3,3) coordinate
color = [int(i) for i in color] # list of integer values of color
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # convert to grayscale
thresh = cv2.threshold(gray, 250, 255, cv2.THRESH_BINARY)[1] # threshold image so that only white grid is left
dst = cv2.inpaint(img.copy(), thresh, 3, cv2.INPAINT_TELEA) # Method 1: perform inpaint
coords = np.argwhere(gray==255) # Method 2: find all coordinates of white pixels
dst2 = img.copy() # hard copy of original image
dst3 = img.copy() # hard copy of original image
# iterate through pixels and draw out the grid (Method 2)
for i in coords:
cv2.circle(dst2, (i[0], i[1]), 3, color, -1) # cirle with radius 3
cv2.circle(dst3, (i[0], i[1]), 1, color, -1) # circle only one pixel
# Write and display images
cv2.imwrite("dst.png", dst)
cv2.imwrite("dst2.png", dst2)
cv2.imwrite("dst3.png", dst3)
cv2.imshow("dst", dst)
cv2.imshow("dst2", dst2)
cv2.imshow("dst3", dst3)
cv2.waitKey(0)
cv2.destroyAllWindows()
结果:
.
方法一
方法2(5像素半径)
添加回答
举报