一、写在前面
寻找字体(物体)的轮廓在深度学习(尤其是语义分割)中具有重要的应用,而这次应用的目标就是使用opencv寻找出字体的轮廓,然后通过轮廓找出字体的笔画,以期待能够找出深度学习模型未识别出的笔画。
二、具体操作
在这里使用两种方法求出轮廓
- 第一种:使用cv2.findContours()求轮廓
- 第二种: 使用Canny算子求轮廓
findContours()
一般的过程是: 读取图像 -> 变成灰度图 -> 黑白底反转(可选)-> 膨胀->高斯滤波(淡化高斯噪声)-> 找出轮廓。
但是使用这种方法,对于识别简单的字体轮廓很好办,对于复杂的字体识别来说,效果不好。
如图所示:
适合简单物体,具体操作代码为:
# 图像的读入
image = cv2.imread(img_path)
# 变成灰度图
img_gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
# 可选 将灰度图黑白反置
h,w = img_gray.shape
img = np.zeros_like(img_gray)
for i in range(h):
for j in range(w):
if ( img_gray[i,j] == 0 ): img[i,j] = 255
else: img[i,j] = 0
得到的图像如图所示:
但是我们需要得到纯白底的轮廓,那该咋办呢?创建另外一个白底图像,然后找出轮廓之后画到白色图像中就行。
# 创建白底图像
new_img = np.zeros_like(image)
new_img.fill(255)
接下来寻找轮廓的代码:
contours, hierarphy = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
# # print(contours[0].shape)
cv2.drawContours(new_img, contours, -1, (0,0,255), 1)
cv2.imshow("new_img",new_img)
cv2.waitKey(0)
就能够得到完整的轮廓了。
Canny算子
而Canny算子使用更加简单,而且适配性更高,能够应对各种复杂的情况,如图所示:
image = cv2.imread(img_path)
# 变成灰度图
img_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 使用Canny算子
edge = cv2.Canny(img_gray, 100, 200)
cv2.imshow("edge", edge)
cv2.waitKey(0)
三、总结
- Canny能够适用于许多复杂的情况,而findContours只能够适用简单的字体