读取图像
首先,加载待处理的图像,可以使用图像处理库(例如OpenCV)来实现这一步。确保已加载正确的图像。
定义特定颜色范围
确定所需的特定颜色范围。这将是要检测的马赛克填充的颜色。需要指定颜色的下限值和上限值,通常以BGR(蓝-绿-红)或HSV(色相-饱和度-明度)颜色空间表示。
转换颜色空间
将图像从BGR颜色空间转换为HSV颜色空间。这是因为在HSV颜色空间中更容易定义颜色范围。
创建颜色掩模
使用颜色的下限值和上限值在HSV图像中创建一个掩模,该掩模会高亮符合颜色范围的区域。掩模是一个二值图像,其中颜色范围内的像素为白色,其他像素为黑色。
寻找颜色区域的轮廓
在掩模图像中,使用图像处理技术(例如轮廓检测)来查找颜色区域的轮廓。每个轮廓代表一个特定颜色的填充矩形。
排除小矩形
在上述步骤中,会得到所有颜色填充区域的轮廓。然后,根据要求排除太小的矩形。可以通过设定一个阈值来过滤掉宽度或高度小于该阈值的矩形。
计算遮罩与标记的交集
对于筛选后的矩形,需要将它们与标记进行比较,以计算遮罩与标记的交集。这包括以下步骤:
获取矩形的坐标和尺寸。
获取标记的坐标和尺寸。
计算遮盖率
计算交集区域的面积并除以标记区域的面积,以获得遮盖率。
分类漏检、误检和正检
每一个标记需指定对应的马赛克,误检、漏检、正检分类规则如下:
无马赛克指定的标记判定为马赛克漏检,遮盖率为0%;
有马赛克但无对应标记的判定为马赛克误检,不计算遮盖率;
有马赛克且有对应标记的判定为马赛克正检,遮盖率为[0%,100%]。
实现代码
#!/anaconda3/envs/FEALPy/bin python3.7
# -*- coding: utf-8 -*-
# ---
# @Software: PyCharm
# @File: get_mosaic.py
# @Author: jerry
# @E-mail: zj850324@yeah.net
# @Site:
# @Time: 10月 13, 2023
# ---
# 计算遮盖率
# ---
import cv2
import numpy as np
def calculate_intersection(mask1, mask2):
# 计算两个掩膜的交集
return cv2.bitwise_and(mask1, mask2)
def extract_and_draw_mosaics(image_path, min_mosaic_size=10, max_display_width=1600, target_color=(181, 230, 29)):
# 读取图像
image = cv2.imread(image_path)
# 计算缩放比例
width, height = image.shape[1], image.shape[0]
scale = max_display_width / width if width > max_display_width else 1.0
new_width = int(width * scale)
new_height = int(height * scale)
# 缩小图像
small_image = cv2.resize(image, (new_width, new_height))
# 定义目标颜色的阈值范围
lower_color = np.array([target_color[2] - 1, target_color[1] - 1, target_color[0] - 1])
upper_color = np.array([target_color[2] + 1, target_color[1] + 1, target_color[0] + 1])
# 使用阈值操作找到目标颜色填充的区域
mask = cv2.inRange(small_image, lower_color, upper_color)
# 查找轮廓
contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 提取满足最小尺寸要求的马赛克并画在图像上
for contour in contours:
x, y, w, h = cv2.boundingRect(contour)
if w >= min_mosaic_size and h >= min_mosaic_size:
# 创建一个与提取的矩形相同大小的mask
mosaic_mask = np.zeros_like(mask)
# 计算差异,假设宽度差异为dw,高度差异为dh
dw, dh = 5, 10
x_offset, y_offset = 5, 5
mosaic_mask[y + y_offset:y + h + y_offset + dh, x + x_offset:x + w + x_offset + dw] = 1
# 计算交集
intersection = np.logical_and(mosaic_mask, mask)
# 计算遮盖率
mosaic_area = mosaic_mask.sum()
intersection_area = intersection.sum()
coverage = intersection_area / float(mosaic_area)
# 画提取的矩形(绿色边框)
cv2.rectangle(small_image, (x, y), (x + w, y + h), (0, 255, 0), 2)
# 画创建的矩形(红色边框)
cv2.rectangle(small_image, (x + x_offset, y + y_offset), (x + x_offset + w + dw, y + y_offset + h + dh),
(0, 0, 255), 2)
print(f"提取的矩形位置:(x: {x}, y: {y}), 宽度: {w}, 高度: {h}")
print(f"创建的矩形位置:(x: {x + x_offset}, y: {y + y_offset}), 宽度: {w + dw}, 高度: {h + dh}")
print(f"遮盖率:{coverage:.2f}")
# 显示图像
cv2.imshow('Image with Mosaics', small_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 使用示例
image_path = './images/1.png' # 图像路径
min_mosaic_size = 10 # 定义最小马赛克大小
max_display_width = 1600 # 定义最大显示宽度
target_color = (181, 230, 29) # 定义目标颜色
extract_and_draw_mosaics(image_path, min_mosaic_size, max_display_width, target_color)
实现效果