themblem/detection/qr_verify_Tool/roi_img_process.py
2024-09-01 21:51:50 +01:00

208 lines
7.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python
# -*- encoding: utf-8 -*-
'''
@File : roi_img_process.py
@Contact : zpyovo@hotmail.com
@License : (C)Copyright 2018-2019, Lab501-TransferLearning-SCUT
@Description :
@Modify Time @Author @Version @Desciption
------------ ------- -------- -----------
2024/1/7 22:57 Pengyu Zhang 1.0 None
'''
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import cv2
import numpy as np
from matplotlib import pyplot as plt
def preprocess_image(image,size,blur):
# 将图像调整为固定大小
# image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
if size !=-1:
image = cv2.resize(image, (size, size), interpolation=cv2.INTER_AREA)
if size == -1:
image = cv2.cvtColor(np.array(image), cv2.COLOR_BGR2GRAY)
if blur:
kernel_size = 3
image = cv2.GaussianBlur(image, (kernel_size, kernel_size), sigmaX=1, sigmaY=0)
return image
def clos_open(input,B_p):
_, binary_image = cv2.threshold(input, B_p, 255, cv2.THRESH_BINARY)
# 定义结构元素(内核)
kernel = np.ones((3, 3), np.uint8)
# 开运算
opening = cv2.morphologyEx(binary_image, cv2.MORPH_OPEN, kernel)
# 定义结构元素(内核)
kernel = np.ones((3, 3), np.uint8)
# 闭运算
closing = cv2.morphologyEx(opening, cv2.MORPH_CLOSE, kernel)
return closing
def img_angle(input):
# canny边缘检测
eroded_canny = cv2.Canny(input, 50, 255, apertureSize=3)
contours, hierarchy = cv2.findContours(eroded_canny, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 寻找最大元素
k = 0
index = 0
if len(contours) != 0:
for i in range(len(contours)):
j = contours[i].size
if j > k:
k = j
index = i
# 拟合旋转矩形
cnt = contours[index]
rect = cv2.minAreaRect(cnt)
angle = rect[2]
box = cv2.boxPoints(rect)
box = np.int0(box)
# 对点按照y坐标排序最上和最下的点
box = box[box[:, 1].argsort()]
# 上边的两个点按照x坐标排序决定左上和右上
top_two = box[:2]
top_two = top_two[top_two[:, 0].argsort()]
# 下边的两个点按照x坐标排序决定左下和右下
bottom_two = box[2:]
bottom_two = bottom_two[bottom_two[:, 0].argsort()]
# 重新组合为左上、右上、右下、左下的顺序
ordered_box = np.array([top_two[0], top_two[1], bottom_two[1], bottom_two[0]])
return angle,ordered_box
def angel_affine(input,angle):
height, width = np.array(input).shape
center = (width // 2, height // 2)
if angle is not None and angle != 0.0:
if angle > 45.0:
angle = angle - 90
# rotate page if not straight relative to QR code
M = cv2.getRotationMatrix2D(center, angle, 1.0)
output = cv2.warpAffine(np.array(input), M, (width, height), flags=cv2.INTER_CUBIC,borderMode=cv2.BORDER_REPLICATE)
return output
def merge_overlapping_rectangles(rectangles):
if len(rectangles) <= 1:
return rectangles
merged_rectangles = []
for rect in sorted(rectangles, key=lambda x: x[2]*x[3], reverse=True):
x, y, w, h = rect
if not any((x < x2 + w2 and x + w > x2 and y < y2 + h2 and y + h > y2) for x2, y2, w2, h2 in merged_rectangles):
merged_rectangles.append(rect)
return merged_rectangles
def roi2_detector(input,min_area_threshold):
# 使用 Canny 边缘检测
edges = cv2.Canny(input, 50, 255, apertureSize=3)
# 寻找轮廓
contours, _ = cv2.findContours(edges, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# 临时存储矩形
temp_rectangles = []
# 识别矩形轮廓
for contour in contours:
# 轮廓近似
epsilon = 0.001 * cv2.arcLength(contour, True)
approx = cv2.approxPolyDP(contour, epsilon, True)
if len(approx) >= 4:
x, y, w, h = cv2.boundingRect(approx)
aspect_ratio = w / float(h)
area_contour = cv2.contourArea(contour)
if aspect_ratio >= 0.75 and aspect_ratio < 1.2 and min_area_threshold < area_contour < 15000:
area_bounding_rect = w * h
area_ratio = area_contour / area_bounding_rect
if 0.75 < area_ratio < 1.05:
temp_rectangles.append((x, y, w, h))
# 合并重叠的方框
merged_rectangles = merge_overlapping_rectangles(temp_rectangles)
# 选择并绘制最大的方框
if merged_rectangles:
outermost_rectangle = max(merged_rectangles, key=lambda x: x[2]*x[3])
rectangle_count = 1
return outermost_rectangle
else:
return None
from PIL import Image
def roi_img_processing(input):
input_ray = cv2.cvtColor(np.array(input), cv2.COLOR_BGR2GRAY)
img_resize = preprocess_image(input_ray, 128, blur=False)
img_closing = clos_open(img_resize,B_p=50) # 闭运算
min_area_threshold=6500
roi_coordinate = roi2_detector(img_closing,min_area_threshold)
if roi_coordinate is None:
img_closing = clos_open(img_resize, B_p=100) # 闭运算
roi_coordinate = roi2_detector(img_closing,min_area_threshold)
if roi_coordinate is None:
return None
x, y, w, h = roi_coordinate
# 截取图像
input_fix = img_resize[y+1:y-1 + h, x+1:x-1 + w]
output = preprocess_image(input_fix, 32, blur=True)
return output
def roi_detect(input):
size = 128
height, width, _ = input.shape
if height < size:
img_resize = cv2.resize(np.array(input), (size, size), interpolation=cv2.INTER_AREA)
else:
img_resize = cv2.resize(np.array(input), (size, size), interpolation=cv2.INTER_LINEAR)
image_gay = cv2.cvtColor(img_resize, cv2.COLOR_BGR2GRAY)
min_area_threshold = 1000
img_closing = clos_open(image_gay, B_p=50) # 闭运算
roi_coordinate = roi2_detector(img_closing,min_area_threshold)
if roi_coordinate is None :
img_closing = clos_open(img_resize, B_p=100) # 闭运算
roi_coordinate = roi2_detector(img_closing,min_area_threshold)
# print('150')
if roi_coordinate is None :
img_closing = clos_open(img_resize, B_p=150) # 闭运算
roi_coordinate = roi2_detector(img_closing,min_area_threshold)
# print('100')
if roi_coordinate is None :
img_closing = clos_open(img_resize, B_p=120) # 闭运算
roi_coordinate = roi2_detector(img_closing,min_area_threshold)
if roi_coordinate is None:
img_closing = clos_open(img_resize, B_p=75) # 闭运算
roi_coordinate = roi2_detector(img_closing,min_area_threshold)
if roi_coordinate is None:
return None
x, y, w, h = roi_coordinate
# 截取图像
input_fix = img_resize[y + 1:y - 1 + h, x + 1:x - 1 + w]
input_fix = Image.fromarray(np.uint8(input_fix))
return input_fix
def roi_minAreaRect(input):
img_closing = clos_open(input) # 闭运算
_, box = img_angle(img_closing) # 图像偏差角度
return box