From 3747f1c0a18a8101f38b93c1fbdf20901e46db4c Mon Sep 17 00:00:00 2001 From: pb8jmewuc <2067353580@qq.com> Date: Tue, 7 Jan 2025 18:03:13 +0800 Subject: [PATCH] ADD file via upload --- img_math.py | 293 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 293 insertions(+) create mode 100644 img_math.py diff --git a/img_math.py b/img_math.py new file mode 100644 index 0000000..96b6430 --- /dev/null +++ b/img_math.py @@ -0,0 +1,293 @@ +# -*- coding: utf-8 -*- +import cv2 +import numpy as np + +MAX_WIDTH = 1000 +Min_Area = 2000 +SZ = 20 +PROVINCE_START = 1000 +""" +该文件包含读文件函数 +取零值函数 +矩阵校正函数 +颜色判断函数 +""" + + +def img_read(filename): + return cv2.imdecode(np.fromfile(filename, dtype=np.uint8), cv2.IMREAD_COLOR) + # 以uint8方式读取filename 放入imdecode中,cv2.IMREAD_COLOR读取彩色照片 + + + + +def point_limit(point): + if point[0] < 0: + point[0] = 0 + if point[1] < 0: + point[1] = 0 + + +def accurate_place(card_img_hsv, limit1, limit2, color): + row_num, col_num = card_img_hsv.shape[:2] + xl = col_num + xr = 0 + yh = 0 + yl = row_num + row_num_limit = 21 + col_num_limit = col_num * 0.8 if color != "green" else col_num * 0.5 # 绿色有渐变 + for i in range(row_num): + count = 0 + for j in range(col_num): + H = card_img_hsv.item(i, j, 0) + S = card_img_hsv.item(i, j, 1) + V = card_img_hsv.item(i, j, 2) + if limit1 < H <= limit2 and 34 < S and 46 < V: + count += 1 + if count > col_num_limit: + if yl > i: + yl = i + if yh < i: + yh = i + for j in range(col_num): + count = 0 + for i in range(row_num): + H = card_img_hsv.item(i, j, 0) + S = card_img_hsv.item(i, j, 1) + V = card_img_hsv.item(i, j, 2) + if limit1 < H <= limit2 and 34 < S and 46 < V: + count += 1 + if count > row_num - row_num_limit: + if xl > j: + xl = j + if xr < j: + xr = j + return xl, xr, yh, yl + + +def img_findContours(img_contours): + contours, hierarchy = cv2.findContours(img_contours, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) + contours = [cnt for cnt in contours if cv2.contourArea(cnt) > Min_Area] + print("findContours len = ", len(contours)) + # 排除面积最小的点 + car_contours = [] + for cnt in contours: + ant = cv2.minAreaRect(cnt) + width, height = ant[1] + if width < height: + width, height = height, width + ration = width / height + + if 2 < ration < 5.5: + car_contours.append(ant) + box = cv2.boxPoints(ant) + + return car_contours + +#进行矩形矫正 +def img_Transform(car_contours, oldimg, pic_width, pic_hight): + car_imgs = [] + for car_rect in car_contours: + if -1 < car_rect[2] < 1: + angle = 1 + # 对于角度为-1 1之间时,默认为1 + else: + angle = car_rect[2] + car_rect = (car_rect[0], (car_rect[1][0] + 5, car_rect[1][1] + 5), angle) + box = cv2.boxPoints(car_rect) + + heigth_point = right_point = [0, 0] + left_point = low_point = [pic_width, pic_hight] + for point in box: + if left_point[0] > point[0]: + left_point = point + if low_point[1] > point[1]: + low_point = point + if heigth_point[1] < point[1]: + heigth_point = point + if right_point[0] < point[0]: + right_point = point + + if left_point[1] <= right_point[1]: # 正角度 + new_right_point = [right_point[0], heigth_point[1]] + pts2 = np.float32([left_point, heigth_point, new_right_point]) # 字符只是高度需要改变 + pts1 = np.float32([left_point, heigth_point, right_point]) + M = cv2.getAffineTransform(pts1, pts2) + dst = cv2.warpAffine(oldimg, M, (pic_width, pic_hight)) + point_limit(new_right_point) + point_limit(heigth_point) + point_limit(left_point) + car_img = dst[int(left_point[1]):int(heigth_point[1]), int(left_point[0]):int(new_right_point[0])] + car_imgs.append(car_img) + + elif left_point[1] > right_point[1]: # 负角度 + new_left_point = [left_point[0], heigth_point[1]] + pts2 = np.float32([new_left_point, heigth_point, right_point]) # 字符只是高度需要改变 + pts1 = np.float32([left_point, heigth_point, right_point]) + M = cv2.getAffineTransform(pts1, pts2) + dst = cv2.warpAffine(oldimg, M, (pic_width, pic_hight)) + point_limit(right_point) + point_limit(heigth_point) + point_limit(new_left_point) + car_img = dst[int(right_point[1]):int(heigth_point[1]), int(new_left_point[0]):int(right_point[0])] + car_imgs.append(car_img) + + return car_imgs + + +def img_color(card_imgs): + colors = [] + for card_index, card_img in enumerate(card_imgs): + + green = yello = blue = black = white = 0 + card_img_hsv = cv2.cvtColor(card_img, cv2.COLOR_BGR2HSV) + # 有转换失败的可能,原因来自于上面矫正矩形出错 + if card_img_hsv is None: + continue + row_num, col_num = card_img_hsv.shape[:2] + card_img_count = row_num * col_num + + for i in range(row_num): + for j in range(col_num): + H = card_img_hsv.item(i, j, 0) + S = card_img_hsv.item(i, j, 1) + V = card_img_hsv.item(i, j, 2) + if 11 < H <= 34 and S > 34: + yello += 1 + elif 35 < H <= 99 and S > 34: + green += 1 + elif 99 < H <= 124 and S > 34: + blue += 1 + + if 0 < H < 180 and 0 < S < 255 and 0 < V < 46: + black += 1 + elif 0 < H < 180 and 0 < S < 43 and 221 < V < 225: + white += 1 + color = "no" + + limit1 = limit2 = 0 + if yello * 2 >= card_img_count: + color = "yello" + limit1 = 11 + limit2 = 34 # 有的图片有色偏偏绿 + elif green * 2 >= card_img_count: + color = "green" + limit1 = 35 + limit2 = 99 + elif blue * 2 >= card_img_count: + color = "blue" + limit1 = 100 + limit2 = 124 # 有的图片有色偏偏紫 + elif black + white >= card_img_count * 0.7: + color = "bw" + colors.append(color) + card_imgs[card_index] = card_img + + if limit1 == 0: + continue + xl, xr, yh, yl = accurate_place(card_img_hsv, limit1, limit2, color) + if yl == yh and xl == xr: + continue + need_accurate = False + if yl >= yh: + yl = 0 + yh = row_num + need_accurate = True + if xl >= xr: + xl = 0 + xr = col_num + need_accurate = True + + if color == "green": + card_imgs[card_index] = card_img + else: + card_imgs[card_index] = card_img[yl:yh, xl:xr] if color != "green" or yl < (yh - yl) // 4 else card_img[yl - (yh - yl) // 4:yh,xl:xr] + + if need_accurate: + card_img = card_imgs[card_index] + card_img_hsv = cv2.cvtColor(card_img, cv2.COLOR_BGR2HSV) + xl, xr, yh, yl = accurate_place(card_img_hsv, limit1, limit2, color) + if yl == yh and xl == xr: + continue + if yl >= yh: + yl = 0 + yh = row_num + if xl >= xr: + xl = 0 + xr = col_num + if color == "green": + card_imgs[card_index] = card_img + else: + card_imgs[card_index] = card_img[yl:yh, xl:xr] if color != "green" or yl < (yh - yl) // 4 else card_img[yl - (yh - yl) // 4:yh,xl:xr] + + return colors, card_imgs + + +# 根据设定的阈值和图片直方图,找出波峰,用于分隔字符 +def find_waves(threshold, histogram): + up_point = -1 # 上升点 + is_peak = False + if histogram[0] > threshold: + up_point = 0 + is_peak = True + wave_peaks = [] + for i, x in enumerate(histogram): + if is_peak and x < threshold: + if i - up_point > 2: + is_peak = False + wave_peaks.append((up_point, i)) + elif not is_peak and x >= threshold: + is_peak = True + up_point = i + if is_peak and up_point != -1 and i - up_point > 4: + wave_peaks.append((up_point, i)) + return wave_peaks + +#分离车牌字符 +def seperate_card(img, waves): + part_cards = [] + for wave in waves: + part_cards.append(img[:, wave[0]:wave[1]]) + + return part_cards + + +def img_mser_color(card_imgs): + colors = [] + for card_index, card_img in enumerate(card_imgs): + green = yello = blue = black = white = 0 + card_img_hsv = cv2.cvtColor(card_img, cv2.COLOR_BGR2HSV) + if card_img_hsv is None: + continue + row_num, col_num = card_img_hsv.shape[:2] + card_img_count = row_num * col_num + for i in range(row_num): + for j in range(col_num): + H = card_img_hsv.item(i, j, 0) + S = card_img_hsv.item(i, j, 1) + V = card_img_hsv.item(i, j, 2) + if 11 < H <= 34 and S > 34: + yello += 1 + elif 35 < H <= 99 and S > 34: + green += 1 + elif 99 < H <= 124 and S > 34: + blue += 1 + if 0 < H < 180 and 0 < S < 255 and 0 < V < 46: + black += 1 + elif 0 < H < 180 and 0 < S < 43 and 221 < V < 225: + white += 1 + color = "no" + if yello * 2 >= card_img_count: + color = "yello" + + elif green * 2 >= card_img_count: + color = "green" + + elif blue * 2 >= card_img_count: + color = "blue" + + elif black + white >= card_img_count * 0.7: + color = "bw" + colors.append(color) + card_imgs[card_index] = card_img + return colors, card_imgs