|
- import cv2
- import numpy as np
- from PIL import Image
- import os.path
- from skimage import io, data
- def stretch(img):
- '''
- 圖像拉伸函數
- '''
- maxi = float(img.max())
- mini = float(img.min())
-
- for i in range(img.shape[0]):
- for j in range(img.shape[1]):
- img[i, j] = (255/(maxi - mini)*img[i, j] - (255 * mini)/(maxi - mini))
-
- return img
- def dobinaryzation(img):
- '''
- 二位元處理函數
- '''
- maxi = float(img.max())
- mini = float(img.min())
-
- x = maxi - ((maxi-mini)/2)
- # 二位元,返回闕值 ret 和 二位元操作後的圖像thresh
- ret, thresh = cv2.threshold(img, x, 255, cv2.THRESH_BINARY)
- #返回二位元的黑白圖像
- return thresh
- def find_rectangle(contour):
- '''
- 尋找矩形輪廓
- '''
- y, x = [],[]
-
- for p in contour:
- y.append(p[0][0])
- x.append(p[0][1])
-
- return [min(y), min(x), max(y), max(x)]
- def locate_license(img, afterimg):
- '''
- 定位車牌號碼
- '''
- contours, hierarchy = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
-
- #找出最大的三個區域
- block = []
- for c in contours:
- #找出輪廓的左下點和右下點,由此計算它的面積與長度筆
- r = find_rectangle(c)
- a = (r[2]-r[0]) * (r[3]-r[1])
- s = (r[2]-r[0]) / (r[3]-r[1])
-
- block.append([r,a,s])
- #選出面積最大的三個區域
- block = sorted(block, key=lambda b: b[1])[-3:]
-
- #使用顏色識別判斷找出最像的車牌區域
- maxweight, maxindex = 0, -1
- for i in range(len(block)):
- b = afterimg[block[i][0][1]:block[i][0][3],block[i][0][0]:block[i][0][2]]
- #BGR轉 HSV
- hsv = cv2.cvtColor(b, cv2.COLOR_BGR2HSV)
- #藍色車牌的範圍
- lower = np.array([100, 50 ,50])
- upper = np.array([140, 255 ,255])
- #根據闕值建模
- mask = cv2.inRange(hsv, lower, upper)
- #統計權值
- w1 = 0
- for m in mask:
- w1 += m/255
-
- w2 = 0
- for n in mask:
- w2 += n
-
- #選出最大權值的區域
- if w2.all() > maxweight:
- maxindex = i
- maxweight = w2
-
- return block[maxindex][0]
- def find_license(img):
- '''
- 預處理函數
- '''
- m = 300 * img.shape[0]/img.shape[1]
- #壓縮圖像
- img = cv2.resize(img, (300, int(m)), interpolation=cv2.INTER_CUBIC)
- #BGR轉換為灰度圖像
- gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
- #灰度拉伸
- stretchedimg = stretch(gray_img)
- '''進行 開運算, 用來去除降噪'''
- r = 16
- h = w = r * 2 + 1
- kernel = np.zeros((h,w), np.uint8)
- cv2.circle(kernel, (r,r), r, 1, -1)
- #開運算
- openingimg = cv2.morphologyEx(stretchedimg, cv2.MORPH_OPEN, kernel)
- #獲取差分圖,兩幅圖像做差 cv2.absdiff('圖像1','圖像2')
- strting = cv2.absdiff(stretchedimg, openingimg)
- #圖像二位元化
- binaryimg = dobinaryzation(strting)
- #canny邊緣檢測
- canny = cv2.Canny(binaryimg, binaryimg.shape[0], binaryimg.shape[1])
- '''清除小的區域,保留大塊的區域,從那定位車牌'''
- #進行閉運算
- kernel = np.ones((5,19), np.uint8)
-
- closingimg = cv2.morphologyEx(canny, cv2.MORPH_CLOSE, kernel)
- #進行開運算
- openingimg = cv2.morphologyEx(closingimg, cv2.MORPH_OPEN,kernel)
- #再次進行閉運算
- kernel = np.ones((5,19), np.uint8)
- closingimg = cv2.morphologyEx(openingimg, cv2.MORPH_CLOSE, kernel)
- #清除小區域,定位車牌
- rect = locate_license(openingimg, img)
-
- return rect, img
- def cut_licence(afterimg, rect):
- '''圖像分割函數'''
- #轉換為寬度和高度
- rect[2] = rect[2] - rect[0]
- rect[3] = rect[3] - rect[1]
- rect_copy = tuple(rect.copy())
- rect = [0, 0, 0, 0]
- #創建模
- mask = np.zeros(afterimg.shape[:2], np.uint8)
- #print ('mask',mask)
- #創建前景模型 大小只能13*5. 行數只能為1. 單通道浮點型
- bgdModel = np.zeros((1, 65), np.float64)
- #cv2.imshow('bgdModel',bgdModel)
- #建前景模型
- fgdModel = np.zeros((1, 65), np.float64)
- #cv2.imshow('fgdModel',fgdModel)
- #分割圖像
- cv2.grabCut(afterimg, mask, rect_copy, bgdModel, fgdModel, 5, cv2.GC_INIT_WITH_RECT)
- mask2 = np.where((mask==2)|(mask==0),0,1).astype('uint8')
- img_show = afterimg*mask2[:,:,np.newaxis]
-
- return img_show
- def deal_license(licenseimg):
- '''
- 車牌圖片二位元化
- '''
- #車牌變為灰度圖像
- gray_img = cv2.cvtColor(licenseimg, cv2.COLOR_BGR2GRAY)
-
- #均值濾波 去除噪音
- kernel = np.ones((3,3), np.float32)/9
- gray_img = cv2.filter2D(gray_img, -1, kernel)
-
- #二位元處理
- ret, thresh = cv2.threshold(gray_img, 120, 255, cv2.THRESH_BINARY)
-
- return thresh
- def find_end(start, arg, block, white, width, black_max, white_max):
- end = start + 1
- for m in range(start+1, width-1):
- if (block[m] if arg else white[m]) > (0.98*black_max if arg else 0.98*white_max):
- end = m
- break
-
- return end
- if __name__ == '__main__':
- img = cv2.imread('a.jpg', cv2.IMREAD_COLOR)
- #預處理圖像
- rect, afterimg = find_license(img)
- #cv2.imshow('img',img)
- #框出車牌號碼
- #cv2.rectangle(img, (x,y), (x+w,y+h), (0,255,0), 2)畫出矩形
- cv2.rectangle(afterimg, (rect[0], rect[1]), (rect[2], rect[3]), (0, 255, 0),2)
- cv2.imshow('afterimg', afterimg)
-
- #分割車牌與背景
- cutimg = cut_licence(afterimg, rect)
- cv2.imshow('cutimg', cutimg)
-
- #二位元生成黑白圖
- thresh = deal_license(cutimg)
- cv2.imshow('thresh', thresh)
- cv2.waitKey(0)
-
- #分割字符
- '''
- 判斷底色和字色
- '''
- #紀錄黑白像素總和
- white = []
- black = []
- height = thresh.shape[0] #263
- width = thresh.shape[1] #400
- #print('height',height)
- #print('width',width)
- white_max = 0
- black_max = 0
- # 計算每一列的黑白像素總和
- for i in range(width):
- line_white = 0
- line_black = 0
- for j in range(height):
- if thresh[j][i] == 255:
- line_white += 1
- if thresh[j][i] == 0:
- line_black += 1
- white_max = max(white_max, line_white)
- black_max = max(black_max, line_black)
- white.append(line_white)
- black.append(line_black)
- #arg為true表示黑底白字, False為白底黑字
- arg = True
- if black_max < white_max:
- arg = False
-
- n = 1
- start = 1
- end = 2
- s_width = 28
- s_height = 28
- while n < width -2:
- n += 1
- #判斷是白底黑字還是黑底白字 0.05參數對應上面的0.95 可做調整
- if (white[n] if arg else black[n]) > (0.02*white_max if arg else 0.02 * black_max):
- start = n
- end = find_end(start, arg, black, white, width, black_max, white_max)
- n =end
- if end - start > 5:
- cj = thresh[1: height, start:end]
-
- #new_image = cj.resize((s_width, s_height), Image.BILINEAR)
- #cj = cj.reshape(28, 28)
- print("result%s.jpg" % (n))
- #保存分割的圖片
- #cj.save("result%s.jpg" % (n))
- #infile = "result%s.jpg" % (n)
- #io.imsave(infile, cj)
- print(n)
- #im = IMage.open(infile)
- #out = im.resize((s_width, s_height), Image.BILINEAR)
- #out.save(infile)
- cv2.imshow('cutlincese', cj)
- cv2.waitKey(0)
-
- cv2.waitKey(0)
- cv2.destroyAllWindows()
複製代碼
參考文章
https://www.itdaan.com/tw/9574009e55291df19eabb41ed6569b99
https://www.itread01.com/content/1556791200.html
文章出處
網頁設計,網站架設 ,網路行銷,網頁優化,SEO - NetYea 網頁設計
|
|