OpenCV 文字识别(一):图像预处理
上一篇的博客中我使用了C++对印刷体汉字进行了预处理,但因为文字识别模型是基于TensorFlow的,C++调用python代码繁杂且容易出错,所以试着用Python代码写整个项目。
总体思路不变:获取直线-->间接获取角度-->旋转
测试代码:
#! /usr/bin/env python
# -*- coding: utf-8 -*-
import cv2
import numpy as np
# 完成灰度化,二值化
def two_value(img_raw):
img_gray = cv2.cvtColor(img_raw, cv2.COLOR_BGR2GRAY) # 灰度化
ret, img_two = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU) # 二值化
return img_two
# 旋转函数
def rotate(img_rotate_raw, angle):
(h, w) = img_rotate_raw.shape[:2]
(cx, cy) = (w//2, h//2)
m = cv2.getRotationMatrix2D((cx, cy), angle, 1.0) # 计算二维旋转的仿射变换矩阵
return cv2.warpAffine(img_rotate_raw, m, (w, h), borderValue=(0, 0, 0))
# 霍夫直线检测
def get_angle(img_hou_raw):
sum_theta = 0
img_canny = cv2.Canny(img_hou_raw, 50, 200, 3)
lines = cv2.HoughLines(img_canny, 1, np.pi/180, 300, 0, 0)
# lines 是三维的
for i in range(lines.shape[0]):
theta = lines[i][0][1]
sum_theta += theta
average = sum_theta / lines.shape[0]
angle = average/np.pi*180 - 90
return angle
def correct(img_cor_raw):
img_two = two_value(img_cor_raw)
angle = get_angle(img_two)
if angle == -1:
print("No lines!!!")
return 0
return rotate(img_two, angle)
if __name__ == "__main__":
img = cv2.imread("D:/pycharm/Word_Lib/xie.jpg")
cv2.imshow("raw", img)
img_rot2 = correct(img)
cv2.imshow("last", img_rot2)
cv2.waitKey()
测试效果(✔)
唯一的问题在于改写原先 lines = cv2.HoughLines(img_canny, 1, np.pi/180, 300, 0, 0)这段代码时,无法使用依次判断,因为最初的默认值得类型是NoneType,而之后则是一个三维数组,会产生矛盾。但因为汉字文本直线清晰,故我选择了较小的阈值:100。
总结:
1.python和C++很大一点不同便是python没有指针,所以一些函数调用的时候要注意返回值,而C++中返回(输出)值写于函数中。
2.python矩阵在概念上要着重理解。写代码时踩了很多坑。
3.pycharm这个IDE很强大,一些语法上的不规范便有各色波浪线,强迫症福利。