在移除棋盘格图案时遇到问题。我使用的是cv2.Threshold,但它也选择了意外的像素(红色标记)。
import cv2 import numpy as np input = cv2.imread('image.png') ret, logo_mask = cv2.threshold(input[:,:,0], 0, 255, cv2.THRESH_BINARY|cv2.THRESH_OTSU) cv2.imshow(logo_mask)
输入图像:
输出图像:
有人能帮忙吗?
trnvg8h31#
获得涵盖所有情况的完美结果具有挑战性。下面的解决方案假定白色棋盘颜色为(255,255,255),灰色为(230,230,230)。另一个假设是在图像的其他部分中具有该特定颜色的聚类非常小。我们可以使用以下阶段:
代码示例:
import cv2 import numpy as np input = cv2.imread('image.png') white_mask = np.all(input == 255, 2).astype(np.uint8)*255 # cv2.inRange(input, (255, 255, 255), (255, 255, 255)) gray_mask = np.all(input == 230, 2).astype(np.uint8)*255 # gray_mask = cv2.inRange(input, (230, 230, 230), (230, 230, 230)) mask = cv2.bitwise_or(white_mask, gray_mask) # Create unified mask ctns = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[-2] # Find contours # Remove small contours from mask for c in ctns: area = cv2.contourArea(c) # Find the area of each contours if (area < 10): # Ignore small contours (assume noise). cv2.drawContours(mask, [c], 0, 0, -1) mask = cv2.dilate(mask, np.ones((3, 3), np.uint8)) # Dilate the mask - "cosmetics" output = cv2.copyTo(input, 255-mask) # Put black color in the masked part. # Show images for testing cv2.imshow('input', input) cv2.imshow('mask', mask) cv2.imshow('output', output) cv2.waitKey() cv2.destroyAllWindows()
white_mask:
white_mask
gray_mask:
gray_mask
mask:
mask
output:
output
如果前景部分存在大的白色区域或灰色区域,则上述解决方案可能不起作用。我想到了一个过程,只寻找白色和灰色矩形之间的边界重叠的区域。它不起作用,因为树分支之间的小部分被排除在外。下面的代码可能会给予你一些启发:
import cv2 import numpy as np input = cv2.imread('image.png') #ret, logo_mask = cv2.threshold(input[:,:,0], 0, 255, cv2.THRESH_BINARY|cv2.THRESH_OTSU) white_mask = np.all(input == 255, 2).astype(np.uint8)*255 # cv2.inRange(input, (255, 255, 255), (255, 255, 255)) gray_mask = np.all(input == 230, 2).astype(np.uint8)*255 # gray_mask = cv2.inRange(input, (230, 230, 230), (230, 230, 230)) cv2.imwrite('white_mask.png', white_mask) cv2.imwrite('gray_mask.png', gray_mask) # Apply opening for removing small clusters opened_white_mask = cv2.morphologyEx(white_mask, cv2.MORPH_OPEN, np.ones((3, 3), np.uint8)) opened_gray_mask = cv2.morphologyEx(gray_mask, cv2.MORPH_OPEN, np.ones((3, 3), np.uint8)) cv2.imwrite('opened_white_mask.png', opened_white_mask) cv2.imwrite('opened_gray_mask.png', opened_gray_mask) white_mask_shell = cv2.dilate(opened_white_mask, np.ones((3, 3), np.uint8)) - opened_white_mask # Dilate white_mask and keep only the "shell" gray_mask_shell = cv2.dilate(opened_gray_mask, np.ones((3, 3), np.uint8)) - opened_gray_mask # Dilate gray_mask and keep only the "shell" white_mask_shell = cv2.dilate(white_mask_shell, np.ones((3, 3), np.uint8)) # Dilate the "shell" gray_mask_shell = cv2.dilate(gray_mask_shell, np.ones((3, 3), np.uint8)) # Dilate the "shell" cv2.imwrite('white_mask_shell.png', white_mask_shell) cv2.imwrite('gray_mask_shell.png', gray_mask_shell) overlap_shell = cv2.bitwise_and(white_mask_shell, gray_mask_shell) cv2.imwrite('overlap_shell.png', overlap_shell) dilated_overlap_shell = cv2.dilate(overlap_shell, np.ones((17, 17), np.uint8)) mask = cv2.bitwise_or(cv2.bitwise_and(white_mask, dilated_overlap_shell), cv2.bitwise_and(gray_mask, dilated_overlap_shell)) cv2.imshow('input', input) cv2.imshow('white_mask', white_mask) cv2.imshow('gray_mask', gray_mask) cv2.imshow('white_mask', white_mask) cv2.imshow('gray_mask', gray_mask) cv2.imshow('opened_white_mask', opened_white_mask) cv2.imshow('opened_gray_mask', opened_gray_mask) cv2.imshow('overlap_shell', overlap_shell) cv2.imshow('dilated_overlap_shell', dilated_overlap_shell) cv2.imshow('mask', mask) cv2.waitKey() cv2.destroyAllWindows()
1条答案
按热度按时间trnvg8h31#
获得涵盖所有情况的完美结果具有挑战性。
下面的解决方案假定白色棋盘颜色为(255,255,255),灰色为(230,230,230)。
另一个假设是在图像的其他部分中具有该特定颜色的聚类非常小。
我们可以使用以下阶段:
代码示例:
white_mask
:gray_mask
:mask
:output
:如果前景部分存在大的白色区域或灰色区域,则上述解决方案可能不起作用。
我想到了一个过程,只寻找白色和灰色矩形之间的边界重叠的区域。
它不起作用,因为树分支之间的小部分被排除在外。
下面的代码可能会给予你一些启发: