HSV分别指的是色相/饱和度/明度,对于黑色和白色的H都为0,在项目中有个小任务是快速计算出衣长,当时实验的服装都为纯色T袖,于是就想到使用HSV来提取出服装的颜色区域进而画出服装的最小轮廓求得衣长。具体实现如下
from matplotlib.path import Path
import cv2
import numpy as np
from matplotlib import pyplot as plt
def get_img_fixl(img):
#图片转正
img2 = np.rot90(img, 1).copy()
h,w = img2.shape[0:2]
#RGB转HSV
hsv_img = cv2.cvtColor(img2,cv2.COLOR_RGB2HSV)
# #提取hsv中H通道数据
h = hsv_img[:, :, 0].ravel()
max_out = np.argmax(np.bincount(h))
max_out = int(max_out)
# plt.hist(h, 180, [0, 180])
# plt.show()
# HSV 的下界限
lower_red = np.array([max_out-6, 30, 90])
# HSV 的上界限
upper_red = np.array([max_out+6, 255, 255])
# 通过上下限提取范围内的掩模mask
mask = cv2.inRange(hsv_img, lower_red, upper_red)
# 腐蚀与膨胀处理
# 定义
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5)) # 定义结构元素的形状和大小
# 腐蚀图像
eroded = cv2.erode(mask, kernel)
# 膨胀图像
dilated = cv2.dilate(eroded, kernel)
out_fixl = np.where(dilated==255)
fixl_y = list(out_fixl)[0]
min_y = min(fixl_y)
max_y = max(fixl_y)
#计算衣服实际尺寸
clothes_long = float((max_y - min_y)*0.215/10)
word_long = str("{:.2f}".format(clothes_long) + " cm")
#在原图上绘制尺寸信息
# cv2.rectangle(im, c1, c2, color, -1, cv2.LINE_AA) # filled
# cv2.putText(im, label, (c1[0], c1[1] - 2), 0, tl / 3, [225, 255, 255], thickness=tf, lineType=cv2.LINE_AA)
point1 = (0,min_y)
point2 = (w,max_y)
cv2.rectangle(img2,point1,point2,(0,0,255),3)
cv2.putText(img2,word_long,(point1[0],point1[1]-5),0,4,[0, 255,0], thickness=2, lineType=cv2.LINE_AA)
return img2
if __name__ == "__main__":
img_path = r'E:\zfkc\PyQt5-YOLOv5-master\detection\test\1\807320220823225229.jpg'
img = cv2.imread(img_path)
out = get_img_fixl(img)
# h,w = out.shape[0:2]
cv2.imwrite("mask16.jpg",out)
# out_fixl = np.where(out==255)
# fixl_x = list(out_fixl)[1]
# min_x = min(fixl_x)
# max_x = max(fixl_x)
#
# #绘制显示
# cv2.line(out,(min_x,0),(min_x,h),(255,0,0),6)
# cv2.line(out,(max_x,0),(max_x,h),(255,0,0),6)
# cv2.imwrite("mask14.bmp",out)