Python 图像处理和文本识别程序:使用 OpenCV 和 EasyOCR
该代码是一个基于 OpenCV 和 EasyOCR 的图像处理和文本识别程序,其主要功能是:
- 读取一张图片,并将其转换为灰度图像。
- 对灰度图像进行直方图均衡和二值化处理,以便更好地识别图像中的轮廓。
- 使用 OpenCV 的 connectedComponentsWithStats 函数找到所有连通区域,并对每个区域填充不同的颜色。
- 使用 OpenCV 的 findContours 函数找到所有轮廓,并使用随机颜色绘制轮廓。
- 使用 EasyOCR 识别图像中的文本,并将其与轮廓匹配,从而确定每个轮廓对应的文本。
- 创建一个邻接矩阵,表示每个轮廓之间的邻接关系。
- 输出识别结果和邻接矩阵。
- 显示处理后的图像和轮廓。
需要注意的是,此代码对于图像中的连通区域大小进行了限制,只有大小在一定范围内的区域才会被绘制和识别。同时,此代码对于邻接关系的判断也是基于连通区域的叠加结果,因此可能存在一定的误差。
import cv2
import numpy as np
import easyocr
import sys
# 创建 OCR 对象,指定要识别的语言
reader = easyocr.Reader(['ch_sim', 'en'])
def generate_random_color():
return np.random.randint(0, 256, 3)
def fill_color(img1, n, img2, stats1):
#获取图像的高度和宽度
h, w = img1.shape
#
res = np.zeros((h, w, 3), img1.dtype)
resregion = np.zeros((h, w, 1), img1.dtype)
# 生成随机颜色
random_color = {}
for c in range(1, n):
zhongjiantu=np.zeros((h, w, 1), img1.dtype)
random_color[c] = generate_random_color()
if stats1[c, 4] < 6000 or stats1[c, 4] > 40000:
# 使用np.where()函数获取要替换像素的坐标
row, col = np.where(img2 == c)
# 将目标像素替换为新值
img2[row, col] = 0
else:
row, col = np.where(img2 == c)
zhongjiantu[row, col]=255
contours, hierarchy = cv2.findContours(zhongjiantu, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(resregion, contours, -1, 255, -1)
# 为不同的连通域填色
for i in range(h):
for j in range(w):
item = img2[i][j]
if item == 0:
pass
else:
res[i, j, :] = random_color[item]
return res,resregion
# 读入图片
img = cv2.imread('zfx2.png')
#先识别文字
results = reader.readtext(img)
# 转换为灰度图像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
#直方图均衡
cv2.equalizeHist(gray,gray)
# 二值化处理
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
#区域断连通
count, dst, stats, centroids = cv2.connectedComponentsWithStats(thresh, ltype=cv2.CV_16U)
result,region = fill_color(gray, count, dst,stats)
# 查找轮廓
contours, hierarchy = cv2.findContours(region, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
print(len(contours))
# 绘制轮廓
for i in range(len(contours)):
area = cv2.contourArea(contours[i])
if area <6000 or area > 40000:
continue
color = (np.random.randint(0, 255), np.random.randint(0, 255), np.random.randint(0, 255))
# 绘制轮廓
#cv2.drawContours(img, cnt,-1,color, -1)
cv2.drawContours(img, contours, i, color,-1)
M = cv2.moments(contours[i])
cx = int(M['m10'] / (M['m00'] + 0.0001))
cy = int(M['m01'] / (M['m00'] + 0.0001))
#写入序号
cv2.putText(img, str(i), (cx, cy), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2, cv2.LINE_AA)
num_contours=len(contours)
#获得给轮廓赋名 创建一个list
sfm=[]
for i in range(num_contours):
for j in range(len(results)):
if cv2.pointPolygonTest(contours[i], (results[j][0][1][0],results[j][0][1][1]), False) == 1:
sfm.append('{}:{}'.format(i,results[j][1]))
#创建一个邻接矩阵
adj_matrix = np.zeros((num_contours, num_contours), dtype=int)
#膨胀轮廓边缘后,记录邻接关系
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
for i in range(num_contours):
#创建一个新矩阵
xintu1 = np.zeros((img.shape[0],img.shape[1], 1), img.dtype)
cv2.drawContours(xintu1,contours,i,255,-1)
xintu1 = cv2.dilate(xintu1, kernel, iterations=1)
for j in range(i+1, num_contours):
xintu2=np.zeros((img.shape[0],img.shape[1], 1), img.dtype)
cv2.drawContours(xintu2, contours, j, 255, -1)
#膨胀操作
xintu2 = cv2.dilate(xintu2, kernel, iterations=1)
#两图叠加
xintu3=cv2.add(xintu1,xintu2)
#计算连通区域的数量、统计数量、信息、质心坐标
count1, dst1, stats1, centroids1 = cv2.connectedComponentsWithStats(xintu3, ltype=cv2.CV_16U)
# 判断两个轮廓是否相邻
if count1 ==2:
adj_matrix[i][j] = 1
adj_matrix[j][i] = 1
else:
continue
#打印结果
print('对应省份:')
for sfm1 in sfm: # 输出识别结果
print(sfm1)
# 显示结果
print('邻接矩阵:')
print(adj_matrix)
cv2.namedWindow('result',cv2.WINDOW_NORMAL)
cv2.imshow('result',result)
cv2.namedWindow('region',cv2.WINDOW_NORMAL)
cv2.imshow('region',region)
cv2.namedWindow('img', cv2.WINDOW_NORMAL)
cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
原文地址: https://www.cveoy.top/t/topic/gDKz 著作权归作者所有。请勿转载和采集!