項(xiàng)目要點(diǎn)
- 讀取圖片:? image = cv2.imread('./images/page.jpg')
- 調(diào)整圖片尺寸:? resized = cv2.resize(image, (width, height), interpolation = cv2.INTER_AREA)
- 灰度化處理:? gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
- 高斯模糊去噪點(diǎn):? gray = cv2.GaussianBlur(gray, (5,5), 0)
- 邊緣檢測(cè):? edged = cv2.Canny(gray, 75, 200)
- cnts = cv2.findContours(edged.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)[0]? 用邊緣檢測(cè)的結(jié)果進(jìn)行輪廓檢測(cè)? # 返回值兩個(gè): contours, hierarchy
- 按照面積排序:? cnts = sorted(cnts, key = cv2.contourArea, reverse = True)
- 顯示輪廓:? image_contours = cv2.drawContours(image.copy(), cnts, -1, (0, 0, 255), 2)
- 計(jì)算輪廓周長(zhǎng):? perimeter = cv2.arcLength(c, True)? # for c in cnts:
- 多邊形逼近:? approx = cv2.approxPolyDP(c, 0.02 * perimeter, True)
- 顯示輪廓: image_contours = cv2.drawContours(image.copy(), [screen_cnt], -1, (0,0,255), 2)?
- 計(jì)算變換矩陣: M =cv2.getPerspectiveTransform(rect,dst) # rect 是原始坐標(biāo),dst 是調(diào)整后坐標(biāo)
- 通過(guò)坐標(biāo)透視變換轉(zhuǎn)換: warped = cv2.warpPerspective(image, M, (max_width, max_height))
- 灰度化處理: warped = cv2.cvtColor(warped, cv2.COLOR_BGR2GRAY)? # 二值化只能處理二維圖片
- 二值化處理: ref = cv2.threshold(warped, 120, 255, cv2.THRESH_BINARY)[1]? # 兩個(gè)返回值: ret, thresh1
- 保存圖片:? cv2.imwrite('./scan1.jpg', ref)
- 圖片轉(zhuǎn)文字:? text = pytesseract.image_to_string(Image.open('./scan1.jpg'))? # 需調(diào)包
- 保存str 到 txt文件:
with open('test.txt','w', encoding='utf-8') as f:
f.write(text)
圖片轉(zhuǎn)文字項(xiàng)目
1 圖片預(yù)處理
1.1 顯示原圖
def cv_show(name, img):
cv2.imshow(name, img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 導(dǎo)包
import numpy as np
import cv2
# 讀取圖片
image = cv2.imread('./images/page.jpg')
print(image.shape) # (3264, 2448, 3)
# 計(jì)算比例,限定高度500
ratio = image.shape[0] / 500.0
orig = image.copy()
cv_show('img', image) # 圖片極大, 看不全...
1.2 圖片尺寸調(diào)整
def resize(image, width = None, height = None, inter = cv2.INTER_AREA):
# cv2.resize()
dim = None
(h, w) = image.shape[:2]
# print(image.shape[:2])
if width is None and height is None:
return image
if width is None: # 只提供了高度
r = height /float(h)
dim = (int(w * r), height)
# print(dim)
else: # 如果只提供了寬度
r = width / float(w)
dim = (width, int(h * r))
resized = cv2.resize(image, dim, interpolation = inter)
return resized
# 對(duì)圖片進(jìn)行 resize
image = resize(orig, height = 500)
cv_show('img', image)
1.3 灰度化處理和輪廓檢測(cè)
# 灰度化處理
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 高斯模糊去噪點(diǎn)
gray = cv2.GaussianBlur(gray, (5,5), 0)
# 邊緣檢測(cè)
edged = cv2.Canny(gray, 75, 200)
cv_show('img', edged)
1.4 輪廓檢測(cè)
# 用邊緣檢測(cè)的結(jié)果進(jìn)行輪廓檢測(cè)
cnts = cv2.findContours(edged.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)[0]
# 按照面積排序
cnts = sorted(cnts, key = cv2.contourArea, reverse = True)
print(len(cnts)) # 16 輪廓數(shù)量
# 顯示輪廓
image_contours = cv2.drawContours(image.copy(), cnts, -1, (0, 0, 255), 2)
cv_show('img', image_contours)
1.5 找出最大輪廓
# 遍歷輪廓,找出最大輪廓
for c in cnts:
# 計(jì)算輪廓周長(zhǎng)
perimeter = cv2.arcLength(c, True)
# 多邊形逼近
approx = cv2.approxPolyDP(c, 0.02 * perimeter, True)
if len(approx) == 4:
screen_cnt = approx
break
# 顯示輪廓
image_contours = cv2.drawContours(image.copy(), [screen_cnt], -1, (0, 0, 255), 2)
cv_show('img', image_contours)
2 透視變換,拉正視角
2.1 透視轉(zhuǎn)換
def order_points(pts):
# 創(chuàng)建全為0 的矩陣, 來(lái)接收找到的坐標(biāo)
rect = np.zeros((4, 2), dtype = 'float32')
s = pts.sum(axis = 1)
# 左上角的坐標(biāo)一定是X,Y相加最小的,右下為最大的
rect[0] = pts[np.argmin(s)]
rect[2] = pts[np.argmax(s)]
# 右上角的x,y 相減的差值一定是最小的
# 左下角的x,y 相減,差值一定是最大的
diff = np.diff(pts, axis = 1)
rect[1] = pts[np.argmin(diff)]
rect[3] = pts[np.argmax(diff)]
return rect
def four_point_transform(image, pts):
rect = order_points(pts)
(tl, tr, br, bl) = rect
widthA = np.sqrt((br[0] - bl[0]) ** 2 + (br[1] - bl[1]) ** 2)
widthB = np.sqrt((tr[0] - tl[0]) ** 2 + (tr[1] - tl[1]) ** 2)
max_width = max(int(widthA), int(widthB))
heightA = np.sqrt((tr[0] - br[0]) ** 2 + (tr[1] - br[1]) ** 2)
heightB = np.sqrt((tl[0] - bl[0]) ** 2 + (tl[1] - bl[1]) ** 2)
max_height = max(int(heightA), int(heightB))
dst = np.array([
[0, 0],
[max_width - 1, 0],
[max_width -1, max_height - 1],
[0, max_height -1]], dtype = 'float32')
M = cv2.getPerspectiveTransform(rect, dst)
warped = cv2.warpPerspective(image, M, (max_width, max_height))
return warped
# 視圖透視變換, 將視圖轉(zhuǎn)為正對(duì)透視
warped = four_point_transform(orig, screen_cnt.reshape(4, 2) * ratio)
# 二值化處理
warped = cv2.cvtColor(warped, cv2.COLOR_BGR2GRAY)
ref = cv2.threshold(warped, 120, 255, cv2.THRESH_BINARY)[1]
print(ref.shape) # (2624, 1962)
cv_show('ref', ref)
# 把處理好的圖片寫(xiě)入文件
cv2.imwrite('./scan1.jpg', ref)
cv_show('warp', warped)
cv2.imwrite('./warped.jpg', warped)
?????
??文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-803256.html
3 tesseract 進(jìn)行識(shí)別
import pytesseract # 調(diào)用電腦的識(shí)圖轉(zhuǎn)文字功能
from PIL import Image
# pytesseract要求的image不是OpenCV讀進(jìn)來(lái)的image, 而是pillow這個(gè)包, 即PIL
text = pytesseract.image_to_string(Image.open('./scan1.jpg'))
print(text)
with open('test.txt','w', encoding='utf-8') as f:
f.write(text)
- 文字識(shí)別結(jié)果
文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-803256.html
到了這里,關(guān)于16- 圖片轉(zhuǎn)文字識(shí)別實(shí)操 (OpenCV系列) (項(xiàng)目十六)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!