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像素半徑)
添加回答
舉報