OpenCV:打破组件之间的单像素桥
OpenCV: Break up single pixel bridges between components
我想对单词图像进行阈值处理并将其拆分为连接的组件(字母)。由于先前的透视变换或分辨率不佳,可能会在字母之间形成单个像素桥。
组件可能相对较薄,这就是简单的腐蚀+膨胀可能会破坏它们的原因。
是否有一种简单的方法可以侵蚀单个像素桥,而无需为桥创建侵蚀内核的所有可能排列?
例1:单词为Pflegt
,字母P
、f
、l
是连在一起的
示例 2:这更严重,CCL 似乎也将甚至不接触面部的区域标记为相同(尽管是 4 连接的)。
来源:
# Label image
ret, thresh = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
connectivity = 4
num_labels, labels, stats, centroids = cv2.connectedComponentsWithStats(thresh, connectivity, cv2.CV_32S)
# Map component labels to hue val
label_hue = np.uint8(179 * labels / np.max(labels))
blank_ch = 255 * np.ones_like(label_hue)
labeled_img = cv2.merge([label_hue, blank_ch, blank_ch])
# cvt to BGR for display
labeled_img = cv2.cvtColor(labeled_img, cv2.COLOR_HSV2BGR)
因此,实现起来有点棘手,尤其是 更严重 图像,但根据我使用此类 像素化 的经验图片,unsharp mask 总有帮助。所以这就是我的尝试:
import numpy as np
import cv2
image = cv2.imread("U:/SO/cca.png")
imgray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# Unsharp mask here
gaussian = cv2.GaussianBlur(imgray, (7, 7), 10.0)
unsharp_image = cv2.addWeighted(imgray, 2.5, gaussian, -1.5, 0, imgray)
cv2.imwrite("cca_2_unsharp.jpg", unsharp_image)
unsharp_image = cv2.erode(unsharp_image, np.ones((3,3), np.uint8), iterations=1)
ret,thresh = cv2.threshold(unsharp_image, 127, 255, cv2.THRESH_BINARY +
cv2.THRESH_OTSU)
cv2.imwrite("cca_2_thresh.jpg", thresh)
connectivity = 4
num_labels, labels, stats, centroids = cv2.connectedComponentsWithStats(thresh,
connectivity, cv2.CV_32S)
# Map component labels to hue val
label_hue = np.uint8(179 * labels / np.max(labels))
blank_ch = 255 * np.ones_like(label_hue)
labeled_img = cv2.merge([label_hue, blank_ch, blank_ch])
# cvt to BGR for display
labeled_img = cv2.cvtColor(labeled_img, cv2.COLOR_HSV2BGR)
cv2.imwrite("cca_2_res.jpg", labeled_img)
结果:
如您所见,更严重 图像的效果仍然相对不佳。在我的试验中,我不需要对第一张图像进行侵蚀,但它不会对结果产生太大影响。我将尝试其他一些方法并更新我的答案。让我知道你的想法!
我想对单词图像进行阈值处理并将其拆分为连接的组件(字母)。由于先前的透视变换或分辨率不佳,可能会在字母之间形成单个像素桥。
组件可能相对较薄,这就是简单的腐蚀+膨胀可能会破坏它们的原因。
是否有一种简单的方法可以侵蚀单个像素桥,而无需为桥创建侵蚀内核的所有可能排列?
例1:单词为Pflegt
,字母P
、f
、l
是连在一起的
示例 2:这更严重,CCL 似乎也将甚至不接触面部的区域标记为相同(尽管是 4 连接的)。
来源:
# Label image
ret, thresh = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
connectivity = 4
num_labels, labels, stats, centroids = cv2.connectedComponentsWithStats(thresh, connectivity, cv2.CV_32S)
# Map component labels to hue val
label_hue = np.uint8(179 * labels / np.max(labels))
blank_ch = 255 * np.ones_like(label_hue)
labeled_img = cv2.merge([label_hue, blank_ch, blank_ch])
# cvt to BGR for display
labeled_img = cv2.cvtColor(labeled_img, cv2.COLOR_HSV2BGR)
因此,实现起来有点棘手,尤其是 更严重 图像,但根据我使用此类 像素化 的经验图片,unsharp mask 总有帮助。所以这就是我的尝试:
import numpy as np
import cv2
image = cv2.imread("U:/SO/cca.png")
imgray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# Unsharp mask here
gaussian = cv2.GaussianBlur(imgray, (7, 7), 10.0)
unsharp_image = cv2.addWeighted(imgray, 2.5, gaussian, -1.5, 0, imgray)
cv2.imwrite("cca_2_unsharp.jpg", unsharp_image)
unsharp_image = cv2.erode(unsharp_image, np.ones((3,3), np.uint8), iterations=1)
ret,thresh = cv2.threshold(unsharp_image, 127, 255, cv2.THRESH_BINARY +
cv2.THRESH_OTSU)
cv2.imwrite("cca_2_thresh.jpg", thresh)
connectivity = 4
num_labels, labels, stats, centroids = cv2.connectedComponentsWithStats(thresh,
connectivity, cv2.CV_32S)
# Map component labels to hue val
label_hue = np.uint8(179 * labels / np.max(labels))
blank_ch = 255 * np.ones_like(label_hue)
labeled_img = cv2.merge([label_hue, blank_ch, blank_ch])
# cvt to BGR for display
labeled_img = cv2.cvtColor(labeled_img, cv2.COLOR_HSV2BGR)
cv2.imwrite("cca_2_res.jpg", labeled_img)
结果:
如您所见,更严重 图像的效果仍然相对不佳。在我的试验中,我不需要对第一张图像进行侵蚀,但它不会对结果产生太大影响。我将尝试其他一些方法并更新我的答案。让我知道你的想法!