在人工智能計算機視覺方面,有圖像分類、目标檢測、語義分割、實例分割四大主要任務。目前在各個領域都有比較成熟的應用。
在一些特定的環境或特殊需求中,我們可能需要通過圖像來對水表進行智能讀數。
水表數據圖像
對于水表讀數,首先考慮使用語義分割,目的就是把水表盤的數據區域分割出來。關于語義分割可以參看:5.人工智能-語義分割。本文主要想講一下語義分割後的圖像數據處理和識别。
語義分割後,返回的是多邊形坐标值。這裡因為可以看到水表的數據區域并不是水平的,所以我們需要根據返回的多邊形坐标值,對水表的數據區域圖像進行旋轉後得到,再進行文字識别。
這裡每個水表圖像對應一個文本文件,文件内容就是語義分割後返回的4個頂點的坐标值。如:97 475 280 424 293 466 105 520
演示數據
實現代碼:
import cv2
import os
import numpy as np
import paddleocr
basedir="meter"
ptslst=[]
#讀取文本文件
for f in os.listdir(basedir):
#分離文件名和後綴
fname,fext=os.path.splitext(f)
if fext==".txt":
#讀取文件
with open(os.path.join(basedir,f)) as f:
for line in f:
#按照空格分割,并轉換為int
x1,y1,x2,y2,x3,y3,x4,y4,v=list(map(lambda x:int(x),line.split()))
#print(x1,y1,x2,y2,x3,y3,x4,y4,v)
dxy={fname:[[x1,y1],[x2,y2],[x3,y3],[x4,y4]]}
ptslst.append(dxy)
#print(ptslst)
#多邊形旋轉為矩形,并計算旋轉角度,返回旋轉後的矩形,中心坐标
def rotate_rect(pts):
#計算多邊形的中心點
x=sum(map(lambda x:x[0],pts))/4
y=sum(map(lambda x:x[1],pts))/4
#計算多邊形的長寬
w=max(map(lambda x:x[0],pts))-min(map(lambda x:x[0],pts))
h=max(map(lambda x:x[1],pts))-min(map(lambda x:x[1],pts))
#計算多邊形的旋轉角度
angle=np.arctan2(pts[1][1]-pts[0][1],pts[1][0]-pts[0][0])*180/np.pi
#旋轉後的矩形
pts_rotate=np.array([[x-w/2,y-h/4],[x w/2,y-h/4],[x w/2,y h/4],[x-w/2,y h/4]])
pts_rotate=pts_rotate.astype(np.int32)
return pts_rotate,angle,x,y
#以(x,y)為中心旋轉圖像
def rotate_img(img,angle,x,y):
#獲取圖像的高和寬
h,w=img.shape[:2]
#計算旋轉後的高和寬
h_new=int(np.sqrt(h**2 w**2-2*h*w*np.cos(angle)))
w_new=int(np.sqrt(h**2 w**2 2*h*w*np.cos(angle)))
#計算旋轉後的中心點
# x_new=w_new/2
# y_new=h_new/2
#計算旋轉矩陣
# M=cv2.getRotationMatrix2D((x_new,y_new),angle,1)
M=cv2.getRotationMatrix2D((x,y),angle,1)
#旋轉圖像
img_rotate=cv2.warpAffine(img,M,(w_new,h_new))
return img_rotate
#讀取圖片,并畫多邊形
for f in os.listdir(basedir):
#分離文件名和後綴
fname,fext=os.path.splitext(f)
if fext==".jpg":
#讀取圖片
img=cv2.imread(os.path.join(basedir,f))
#畫多邊形
for dxy in ptslst:
if fname in dxy:
#轉換為np.array
pts=np.array(dxy[fname])
#cv2.polylines(img,[pts],True,(0,255,0),2)
#返回旋轉後坐标,旋轉角度,中心點
pts_m,theta,x,y=rotate_rect(pts)
#print(pts_m)
#旋轉圖像
img=rotate_img(img,theta,x,y)
#cv2.polylines(img,[pts_m],True,(0,0,255),2)
#獲取旋轉後矩形的圖像
roi_img=img[pts_m[0][1]:pts_m[2][1],pts_m[0][0]:pts_m[2][0]]
#ocr識别
ocr=paddleocr.PaddleOCR(use_angle_cls=True,lang="ch")
result=ocr.ocr(roi_img,cls=True)
line=result[0]
boxes=line[0]
txts=line[1][0]
scores=line[1][1]
#print(boxes,txts,scores)
#寫文字
cv2.putText(roi_img,txts,(10,25),cv2.FONT_HERSHEY_SIMPLEX,1,(0,0,255),2)
cv2.imshow("meter",roi_img)
#顯示圖片
#cv2.imshow("img",img)
cv2.waitKey(0)
cv2.destroyAllWindows()
旋轉後識别結果
,更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!