难点
前方草坪颜色带来的干扰
HSV提取小工具
import numpy as np
import cv2
# 存储点击点的HSV值
clicked_points_hsv = []
def on_mouse_click(event, x, y, flags, param):
global img_hsv
if event == cv2.EVENT_LBUTTONDOWN:
# 获取点击位置的HSV值
hsv = img_hsv[y, x]
clicked_points_hsv.append(hsv)
print(f"Clicked HSV: {hsv}")
# 读取图像
img_bgr = cv2.imread('example.jpg')
# 将图像转换为HSV颜色空间
img_hsv = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2HSV)
# 创建窗口并设置鼠标回调函数
cv2.namedWindow('image')
cv2.setMouseCallback('image', on_mouse_click)
while True:
cv2.imshow('image', img_bgr)
key = cv2.waitKey(1)
if key == ord('q'):
break
cv2.destroyAllWindows()
# 计算点击点的HSV值范围
if clicked_points_hsv:
clicked_points_hsv = np.array(clicked_points_hsv)
hsv_min = np.min(clicked_points_hsv, axis=0)
hsv_max = np.max(clicked_points_hsv, axis=0)
print(f"\nHSV Range:\nMin: {hsv_min}\nMax: {hsv_max}")
else:
print("No points clicked.")
点击图片区域输出对应HSV值,退出程序时返回刚刚点击的HSV的范围(最大值最小值)
升级版:传入图像列表,对所有图像进行操作
import numpy as np
import cv2
# 存储点击点的HSV值
clicked_points_hsv = []
def on_mouse_click(event, x, y, flags, param):
global img_hsv
if event == cv2.EVENT_LBUTTONDOWN:
# 获取点击位置的HSV值
hsv = img_hsv[y, x]
clicked_points_hsv.append(hsv)
print(f"Clicked HSV: {hsv}")
# 读取图像
image_files = ['example.jpg', '1.jpg', '6.jpg'] # 图像文件列表
for file in image_files:
# 读取图像
img_bgr = cv2.imread(file)
# 将图像转换为HSV颜色空间
img_hsv = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2HSV)
# 创建窗口并设置鼠标回调函数
cv2.namedWindow('image')
cv2.setMouseCallback('image', on_mouse_click)
while True:
cv2.imshow('image', img_bgr)
key = cv2.waitKey(1)
if key == ord('q'):
break
cv2.destroyAllWindows()
# 计算点击点的HSV值范围
if clicked_points_hsv:
clicked_points_hsv = np.array(clicked_points_hsv)
hsv_min = np.min(clicked_points_hsv, axis=0)
hsv_max = np.max(clicked_points_hsv, axis=0)
print(f"\nHSV Range:\nMin: {hsv_min}\nMax: {hsv_max}")
else:
print("No points clicked.")
图像处理实例
import numpy as np
import cv2 as cv2
# 读取图像
frame = cv2.imread('example.jpg')
# frame = cv2.GaussianBlur(frame, (3, 3), 0)
# 转换颜色空间 BGR 到 HSV
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
hsv = cv2.GaussianBlur(hsv, (3, 3), 0)
# 定义HSV中green的范围
lower_blue = np.array([62, 118, 111])
upper_blue = np.array([80, 185, 164])
# 设置HSV的阈值使得只取green
mask = cv2.inRange(hsv, lower_blue, upper_blue)
# 使用十字结构元素,开运算消除环境中多余的绿色点线,闭运算消除黑点
kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, (5, 5))
open = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel, iterations=4)
close = cv2.morphologyEx(open, cv2.MORPH_CLOSE, kernel, iterations=4)
cv2.imshow('close.jpg', close)
# 得到图像边界
contours, hierarchy = cv2.findContours(close, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# 创建空白图像用于绘制轮廓
rows, cols = close.shape
contour_image = np.ones((rows, cols, 3), dtype=np.uint8) * 255
# 绘制轮廓
cv2.drawContours(contour_image, contours, -1, (0, 255, 0), 2)
# 显示结果
cv2.imshow('pic.jpg', contour_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
原图如图所示,可以提取出中心的回型区域。使用前面的HSV提取小工具获得数据,修改后面代码中的值就可以获得比较好的效果。而且方便切换场景和光线效果时也能迅速调整。
然鹅使用多图像HSV提取后,干扰项会变得明显起来,不能总是满足所有图片的需求。
可以看到前面一块绿色草皮的版产生了很大的干扰,对此我做出以下改进
分别设置开运算和闭运算的核大小,使得开运算核更大,消除更多的不规则白点,闭运算核相对较小,保留原规则图像更多的细节。
# 使用十字结构元素,开运算消除环境中多余的绿色点线,闭运算消除黑点
kernel_open = cv2.getStructuringElement(cv2.MORPH_RECT, (7, 7))
kernel_close = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
# kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, (5, 5))
open = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel_open, iterations=4)
close = cv2.morphologyEx(open, cv2.MORPH_CLOSE, kernel_close, iterations=4)
与上方最后一张图是同一张图处理后的效果,可以看到白色噪音得到有效减少