python 如何使中置管手检戴手套在手上进行

gr8qqesn  于 2023-05-27  发布在  Python
关注(0)|答案(1)|浏览(134)

我试图使mediapipe的手部检测能够真实的地在戴着蓝色手套的手上工作。但它不能正常工作。如果颜色与肤色相似,则检测仍然可以在手套上工作。所以,我尝试做一些预处理,其中我改变了蓝色像素上发现的帧到裸色。结果是它无法准确地检测到手-有时它可以,但它后来会消失。
请帮我解决这个问题。我在某个地方读到过,这种手部检测可以通过将手套的颜色改变为肤色,同时保留手部的阴影来真实的工作在蓝色手套上。但我不知道该怎么做。如果你能帮助我,我将不胜感激。

def findHands(self, img, draw=True, flipType=True):
 imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

 blue  = [0,0,255]
 nude=[225, 190, 160]

 #Make mask 
 Bmask = np.all(imgRGB == blue, axis=-1)

 #Replace blue pixel into nude
 imgRGB[Bmask] = nude

 img_res=imgRGB

 #Send frame to mediapipe        
 self.results = self.hands.process(img_res)
8wigbo56

8wigbo561#

最简单的解决方案是省略cv2.cvtColor(),这将导致图像通道交换,有效地使blue看起来像orange。下面是一个例子(对于mediapipe==0.9.0):

import cv2
import mediapipe as mp
mp_drawing = mp.solutions.drawing_utils
mp_drawing_styles = mp.solutions.drawing_styles
mp_hands = mp.solutions.hands

with mp_hands.Hands(
    static_image_mode=True,
    max_num_hands=2,
    min_detection_confidence=0.5) as hands:
        image = cv2.imread("gloves.jpg")
        results = hands.process(image)

        if results.multi_hand_landmarks:
            image_height, image_width, _ = image.shape
            for hand_landmarks in results.multi_hand_landmarks:
                mp_drawing.draw_landmarks(
                    image,
                    hand_landmarks,
                    mp_hands.HAND_CONNECTIONS,
                    mp_drawing_styles.get_default_hand_landmarks_style(),
                    mp_drawing_styles.get_default_hand_connections_style())
        else:
            print("no hands were found")
                
        cv2.imshow("result", image)
        cv2.waitKey(0)

这应该足以让MediaPipe识别手牌:

或者,您也可以使用HSV模式(adapted from here)中的色调偏移对颜色变化进行微调。这将是一个“更好”的解决方案,因为它只改变色调,但不交换通道。
**编辑:**我创建了一个简单的色调调整“类似GUI”的脚本,可以帮助找到合适的色调偏移:

import cv2
import mediapipe as mp
mp_drawing = mp.solutions.drawing_utils
mp_drawing_styles = mp.solutions.drawing_styles
mp_hands = mp.solutions.hands

window_title = 'Recognition result'
trackbar_title = 'Hue offset'

class HueHelper:
    def __init__(self):
        self.mp_hands = mp_hands.Hands(static_image_mode=True,
                                        max_num_hands=2,
                                        min_detection_confidence=0.5)
        self.img_bgr = None

    def apply_hue_offset(self,image, hue_offset):# 0 is no change; 0<=huechange<=180
        # convert img to hsv
        img_hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
        h = img_hsv[:,:,0]
        s = img_hsv[:,:,1]
        v = img_hsv[:,:,2]
        # shift the hue
        # cv2 will clip automatically to avoid color wrap-around
        img_hsv = cv2.add(h, hue_offset)
        # combine new hue with s and v
        img_hsv = cv2.merge([img_hsv,s,v])
        # convert from HSV to BGR
        return cv2.cvtColor(img_hsv, cv2.COLOR_HSV2BGR)

    def on_trackbar_change(self, trackbar_hue_offset):
        img_bgr_modified = self.recognize(self.img_bgr.copy(), trackbar_hue_offset)
        cv2.imshow(window_title, img_bgr_modified)

    def recognize(self, img_bgr, hue_offset):
        img_bgr = self.apply_hue_offset(img_bgr, hue_offset)
        img_rgb = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB)
        results = self.mp_hands.process(img_rgb)

        if results.multi_hand_landmarks:
            for hand_landmarks in results.multi_hand_landmarks:
                mp_drawing.draw_landmarks(
                    img_bgr,
                    hand_landmarks,
                    mp_hands.HAND_CONNECTIONS,
                    mp_drawing_styles.get_default_hand_landmarks_style(),
                    mp_drawing_styles.get_default_hand_connections_style())
        else:
            print('no hands were found')
        return img_bgr
    
    def run(self, img_path):
        self.img_bgr = cv2.imread(img_path)
        if self.img_bgr is None: print('Image was not found!')
        self.on_trackbar_change(0)
        # Hue range is 0-179: https://docs.opencv.org/4.x/df/d9d/tutorial_py_colorspaces.html
        cv2.createTrackbar(trackbar_title, window_title, 0, 179, self.on_trackbar_change)
        cv2.waitKey(0)
        cv2.destroyAllWindows()

if __name__ == '__main__':
    h = HueHelper()
    h.run('gloves.jpg')

再来一个demo:

相关问题