基本 hsb 皮肤检测,霓虹灯照明
信息处理
图像处理
计算机视觉
2021-12-30 05:30:12
4个回答
使用 RGB 而不是 HSV 中的简单生成模型,这实际上可能会更好。
- 获取一张或几张带有一些皮肤的训练图像。
- 手动选择皮肤像素(例如通过创建二进制蒙版)
- 计算 RGB 中肤色的均值和协方差(每个都应该是 3 元素向量)
- 对于未知像素,使用协方差计算其与平均值的马氏距离。
- 如果距离小于阈值,则将其分类为皮肤。
- 调整阈值以获得最佳性能。
编辑: 我不知道 OpenCV 是否有计算协方差的功能,但我可以告诉你如何自己做。假设您有RGB 像素。您将它们放入一个 x 3 矩阵中,我们称之为。然后通过计算列的平均值计算,这是平均 RGB 向量。 将是一个 1 x 3 向量。的每一行中减去并调用生成的矩阵。现在要计算协方差,您所要做的就是将乘以自身的转置:。确保为 3 x 3。
Edit2: 你得到的值似乎太大了。要获得最大协方差,请创建以下矩阵:
255 255 255
0 0 0
并计算它的协方差。您应该得到一个矩阵,其中每个值都大约为 32513。因此,请确保您的像素值范围从 0 到 255,并确保将它们正确复制到浮点数或双精度数中。Mahalanobis 距离以方差为单位,因此数字应该很小。您的皮肤分类阈值可能应该小于 4。
到目前为止,您得到的答案都指向了很好的替代方法,但是如果您对使用初始算法之类的东西感兴趣,那么修复它可能并不难。您只需要针对 OpenCV 的 HSV 特性进行调整。鉴于古怪的结果,我假设您在选择阈值和/或转换像素时可能使用了 HSV 更常见的数字表示之一?
OpenCV 表示 HSV 的方式与您可能发现的大多数其他来源不同:
- 对您来说最大的区别是 w/r/t 色调:OpenCV 将色调表示为从 0 到 179,而几乎所有其他东西都利用悬挂位来保存更多信息,w/0-255。
- 另一个区别:与标准相比,饱和度的测量是倒置的。所以 255 饱和度在 opencv 中意味着明亮,而不是白色(注意,我们回到 255 - 只有色调是 0-180,可能是因为“轮”表示?)
可能为时已晚,但这是一个有趣的问题,其他人可能会遇到同样的问题。
import sys
import numpy
import cv2
cap = cv2.VideoCapture(0)
while(1):
_, im = cap.read()
im_ycrcb = cv2.cvtColor(im, cv2.COLOR_BGR2YCR_CB)
skin_ycrcb_mint = numpy.array((0, 133, 77))
skin_ycrcb_maxt = numpy.array((255, 173, 127))
skin_ycrcb = cv2.inRange(im_ycrcb, skin_ycrcb_mint, skin_ycrcb_maxt)
cv2.imshow("Second Image", skin_ycrcb) # Second image
contours, _ = cv2.findContours(skin_ycrcb, cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
for i, c in enumerate(contours):
area = cv2.contourArea(c)
if area > 1000:
cv2.drawContours(im, contours, i, (255, 0, 0), 3)
cv2.imshow("Final Image", im) # Final image
cv2.waitKey(1)