Study/Python | FastAPI

[Python] hsv를 사용해서 색상 변경하기

nam-willow 2024. 12. 21. 01:38

이전에 작성했던 코드에서 치명적 오류

  • 명도가 조금만 밝으면 아예 이미지가 깨지는 현상 발생... 이를 해결하려고 명도를 확인해서 수정하는 코드 작성
  • 명도가 205이하면 어둡다고 생각해서 +50 하고, 205 이상이면 +50 했을때 이미지가 깨지는 경우가 발생해서 numpy를 사용해서 처리해줫음
def color(self, request_param: models.Color, 일부 생략):

        rgb_color = self.parse_color(request_param.rgb,request_param.hex, request_param.hsl)

        # 변경할 색상 값
        newColor = {'R': rgb_color[0], 'G': rgb_color[1], 'B': rgb_color[2]}  # 변경할 색상 값
        # newColor = {'R': 255, 'G': 127, 'B': 127}  # 변경할 색상 값
        r = newColor['R']
        g = newColor['G']
        b = newColor['B']
        bgr_color = (b, g, r)

        (...중간 생략)

        # 원본 이미지를 HSV 색상공간으로 변환  
        hsv_image = cv2.cvtColor(originalImage, cv2.COLOR_BGR2HSV)

        # BGR 색상 값을 HSV로 변환
        hsv_color = cv2.cvtColor(np.uint8([[bgr_color]]), cv2.COLOR_BGR2HSV)
        hsv_color = hsv_color[0][0]

        # hsv
        hue=hsv_color[0]        # hsv모드의 색조 값 담아주기
        saturation=hsv_color[1] # hsv모드의 채도 값 담아주기

        # check 영역(흰색)의 boolean 생성
        # 색상이 255(흰색)내용을 트루로 표시
        check = (segmentedImage == 255)

        # check 영역에(True)만 Hue와 Saturation을 변경
        hsv_image[:, :, 0][check] = hue # 색조
        hsv_image[:, :, 1][check] = saturation # 채도

        # check에 해당하는 영역의 명도를 가져온다
        value_channel = hsv_image[:, :, 2][check] 
        lower_brightness_areas = value_channel <= 205
        hsv_image[:, :, 2][check][lower_brightness_areas] = np.clip(value_channel[lower_brightness_areas] + 50, 0, 255)

        # HSV 이미지를 BGR 색상 값으로 변경
        # 이게 결과값
        image = cv2.cvtColor(hsv_image, cv2.COLOR_HSV2BGR)


        (이하 생략...)
    # request_param == 색상값
    def parse_color(self, rgb, hex, hsl): 
        # rgb값으로 변경 -> 튜플로 변환
        if hex:
            hex_color = hex.lstrip('#')
            rgb_values = tuple(int(hex_color[i:i+2], 16) for i in (0, 2, 4))
            return rgb_values
        # 튜플로 변환
        if rgb:
            rgb_values = tuple(map(int, rgb.split(',')))
            return rgb_values