放假前寫的代碼,pip更新了連註釋都不能寫,現在看一下真不知道自己寫了什麼鬼。最邪的是我的能在當前py文件下調用函數生成imread的對象,但是在測試文件就不行,檢查過絕對路徑和相對路徑沒有中文,我嘗試通過導入imread對象還是None,我納悶了。所以我決定還是把測試寫到同一個地方吧。車牌已經打馬賽克。
目錄
1 安裝
正常pip就行,pycharm會有init錯誤,Linux下沒有錯誤。
2 代碼實現
2.1 調整圖片
def pic_resize(img, max_width=1000):
"""
調整車牌的大小
:param img: 傳入的圖片
:param max_width: 最大的寬度默認1000
:return: 返回車牌
"""
print("168h,The function'{}' is running.".format(sys._getframe().f_code.co_name))
height, width = img.shape[:2]
if width > max_width:
change_rate = max_width / width
# 基於局部像素的重採樣
img = cv2.resize(img, (max_width, numpy.int(change_rate * height)), interpolation=cv2.INTER_AREA)
return img
測試
if __name__ == '__main__':
img = cv2.imread(JPG)
# test pic_resiz
height, width = img.shape[:2]
print("164h,The original height:", height, "px width:", width, "px")
res = pic_resize(img)
print("169h,The original height:", res.shape[0], "px width:", res.shape[1], "px")
結果
64h,The original height: 1632 px width: 2048 px
168h,The function'pic_resize' is running.
169h,The original height: 796 px width: 1000 px
Process finished with exit code 0
2.2 去噪聲
# erode&dita
def pic_open(img):
# 轉成灰度圖像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 閾值處理
ret, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_OTSU | cv2.THRESH_BINARY)
# 返回符合的地方,並用矩形圈起來
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
# 去燥有一些小的矩形,去除邊緣毛躁
er = cv2.erode(binary, kernel)
# 進行膨脹操作
di = cv2.dilate(binary, kernel)
img = cv2.add(er, di)
return img
測試
# main函數中
cv2.imshow("carshow",img)
img = pic_open(img)
cv2.imshow("pic_open", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
結果
2.3 Candy邊緣檢測
def pic_extract_edge(binary):
"""
candy邊緣檢測
:param binary:
:return:
"""
can_res = cv2.Canny(binary, 50, 150)
# cv2.imwrite("write_pic/car_plate_pic/edge50_150.jpg", can_res)
kernel = numpy.ones((25, 25), numpy.uint8)
img_edge = cv2.morphologyEx(can_res, cv2.MORPH_CLOSE, kernel)
img_edge = cv2.morphologyEx(img_edge, cv2.MORPH_OPEN, kernel)
# cv2.imwrite("write_pic/car_plate_pic/pic_tract_edge_openclose_25.jpg", img_edge)
contours, hierarchy = cv2.findContours(img_edge, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
return contours
因爲之前有write結果所以直接看圖片
2.4 提取車牌號
要用提取最小的矩形,因爲從圖片可知馬路上會有虛線或者是旁邊的草叢或者是其他很多的干擾。
def get_ratio(rect):
"""
用於計算長寬之比
rect:傳入一個矩形
"""
width, height = rect[1]
if width > height:
ratio = width / height
else:
ratio = height / width
return ratio
def is_car_plate_box(rect):
"假如比例是2.5到4自檢都是可以檢測出車牌的"
if 2.5 < get_ratio(rect) < 4:
return True
return False
# extract car plate
def pic_extract_car_plate(contours, minarea=8100, maxarea=11400):
car_plates = []
for contour in contours:
if minarea < cv2.contourArea(contour) < maxarea:
#找最小面積的矩形
rect = cv2.minAreaRect(contour)
if is_car_plate_box(rect):
car_plates.append(contour)
# print(len(car_plates))
return car_plates
圖取到以後就可以把它在原圖標識出來
def pic_draw_car_plates(src, car_plates):
if len(car_plates) != 1:
print("The length of the car_plates should be 1. I need to adjust the parameters.")
return
plate_result = None
for plate in car_plates:
ltx, lty, rbx, rby = get_position(plate)
cv2.rectangle(src, (ltx, lty), (rbx, rby), (0, 0, 255), 2)
# print(ltx, lty, rbx, rby)
plate_result = src[lty:rby, ltx:rbx, :]
return plate_result
# cv2.imshow("carshow", src)
# cv2.imshow("plate_result", plate_result)
# cv2.imwrite("write_pic/car_plate_pic/pic_draw_car_plates(src).jpg", src)
# cv2.imwrite("write_pic/car_plate_pic/pic_draw_car_plates(plate_result).jpg", plate_result)
結果