opencv圖像識別車牌

放假前寫的代碼,pip更新了連註釋都不能寫,現在看一下真不知道自己寫了什麼鬼。最邪的是我的能在當前py文件下調用函數生成imread的對象,但是在測試文件就不行,檢查過絕對路徑和相對路徑沒有中文,我嘗試通過導入imread對象還是None,我納悶了。所以我決定還是把測試寫到同一個地方吧。車牌已經打馬賽克。

目錄

1 安裝

2 代碼實現

2.1  調整圖片

2.2  去噪聲

2.3 Candy邊緣檢測

2.4 提取車牌號


 

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)

結果

 

 

發佈了47 篇原創文章 · 獲贊 81 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章