본문 바로가기
기타👨🏻‍💻/AI

[AI] 이미지 웹 접근성 ( openCV - 색대비 체크 )

by 텅빈비니 2025. 3. 17.
반응형

안녕하세요🐶

빈지식 채우기의 비니🙋🏻‍♂️ 입니다.

 

사내 AI 프로젝트를 진행하면서,

웹 접근성에 대해 공부할 기회가 생겼습니다. 바로 예시로 확인해보도록 하죠!

웹 접근성 색대비 이미지 예시

상기 이미지를 보면 알 수 있듯이,

푸른색 배경의 "안녕하세요" 는 가독성이 좋아서 보기 편합니다.

하지만 노란색 배경의 "안녕하세요" 는 무슨 글자인지 잘 보이지 않는데요. 

이렇게 간단하게 색상 만으로 웹 접근성을 체크할 수 있습니다.

 

기존에는 작업자가 수작업으로 하나하나 체크를 했었습니다.

다만, 이러한 이미지가 100장...1000장....10000장이라면..?

너무나 많은 리소스가 투입될 것이고 작업 효율도 좋지 못할 것으로 생각됩니다.

 

하지만!!

만약 아래와 같은 프로세스를 가진 시스템이 있다면 어떨까요?.?

  1. 이미지 내의 객체를 찾는다.
  2. 찾은 객체의 색대비를 체크한다 ( WCAG 기준 )
  3. 웹 접근성 색대비에 부적합한 것을 이미지에 자동으로 표시한다.

딸깍딸깍 몇번으로 손 쉽게 웹 접근성 적합 유무를 파악할 수 있습니다.

그럼! 바로 소스를 통해 설명을 해드리겠습니다!


1. 소스 예제

## 1. 라이브러리 Import
import cv2			// 객체 찾기를 위한 opencv 라이브러리
import numpy as np		// 객체의 색상 추출을 위한 numpy 라이브러리
  • 객체를 찾고 찾은 객체의 색상 추출을 위한 라이브러리를 추가합니다.
    • openCV
    • numpy
## 2. OpenCV를 사용한 감지 (객체명을 YOLO 감지된 객체와 매칭)
def detect_Object(image):
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    edges = cv2.Canny(gray, 50, 150)
    contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    objects = []
    for cnt in contours:
        approx = cv2.approxPolyDP(cnt, 0.02 * cv2.arcLength(cnt, True), True)
        if len(approx) >= 7:  # 형태 필터링
            x, y, w, h = cv2.boundingRect(cnt)
            objects.append((x, y, x + w, y + h, "Object"))

    return image, objects
  • openCV를 이용하여 이미지 내의 존재하는 객체를 감지합니다.
    • 추가로 좌표 값 또한 추출하여 전달합니다.
## 3. 색상의 휘도(Luminance) 계산
def calculate_luminance(color):
    def linearize(c):
        c = c / 255.0
        return c / 12.92 if c <= 0.03928 else ((c + 0.055) / 1.055) ** 2.4

    r, g, b = color
    return 0.2126 * linearize(r) + 0.7152 * linearize(g) + 0.0722 * linearize(b)
  • 웹 접근성 색대비 체크를 위해 색상 계산을 합니다.
## 4. 두 색상의 대비 비율 계산
def contrast_ratio(color1, color2):
    lum1 = calculate_luminance(color1)
    lum2 = calculate_luminance(color2)
    l1, l2 = max(lum1, lum2), min(lum1, lum2)
    return (l1 + 0.05) / (l2 + 0.05)
  • 객체의 색상 값과 객체 주변 배경의 색상 값을 비교해서 색 대비 값을 추출합니다.
## 5. 객체 색상과 배경색을 비교하여 대비 분석
def analyze_contrast(image, boxes):
    contrast_results = []

    for (x1, y1, x2, y2, label) in boxes:
        obj_color = np.mean(image[y1:y2, x1:x2], axis=(0, 1))  # 객체 색상 추출
        bg_x, bg_y = max(0, x1 - 5), max(0, y1 - 5)  # 배경 샘플링
        bg_color = image[bg_y, bg_x]

        ratio = contrast_ratio(obj_color, bg_color)
        status = "✅ 적합" if ratio >= 4.5 else "❌ 부적합 (WCAG 기준 미달)"

        if ratio >= 4.5:    # ✅ 적합
            cv2.rectangle(image, (x1, y1), (x2, y2), (0, 0, 255), 2)
        else:               # ❌ 부적합
            cv2.rectangle(image, (x1, y1), (x2, y2), (255, 0, 0), 2)

        cv2.putText(image, "Object", (x1, y1 - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)
        result = {
            "label": label, 
            "object_color": obj_color, 
            "background_color": bg_color, 
            "contrast_ratio": ratio, 
            "status": status, 
            "location": f"(위치: {x1}, {y1}, {x2}, {y2})"
            }
        contrast_results.append(result)

        # 대비 비율 표시
        cv2.putText(image, f"{label}: {ratio:.2f}", (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2)

    return image, contrast_results
  • 객체의 값 ( 좌표 포함 ) 과 해당 객체의 색 대비를 통해 웹 접근성 적합 유무를 판단합니다. ( WCAG 기준 )
  • 적합 유무를 판단하여 원본 이미지에 그려줍니다.
    • 적합 시 : 적색 사각형 표시
    • 부적합 시 : 푸른색 사격형 표시
## 6. 상기 기능들을 호출하는 함수를 정의합니다.
def analyze_accessibility(image_path):
    # 이미지 로드
    image = cv2.imread(image_path)

    # OpenCV를 사용한 객체 감지 (객체명 반영)
    image, detect_boxes = detect_Object(image)

    # 모든 객체 박스 합치기 (YOLO + OpenCV)
    all_boxes = [(x1, y1, x2, y2, label) for (x1, y1, x2, y2, label) in detect_boxes]

    # 대비 분석 실행
    image, contrast_results = analyze_contrast(image, all_boxes)

    # 결과 이미지 저장
    cv2.imwrite("./result/output_accessibility.png", image)
    print(f"📌 분석 완료! 결과 이미지는 'output_accessibility.png'에 저장됨.")
    return contrast_results
# 실행 예제
image_path = "####.png"
contrast_results = analyze_accessibility(image_path)

# 웹 접근성 기준 검토
for result in contrast_results:
    print(f"🖌️ 객체: {result['label']}, 대비 비율: {result['contrast_ratio']:.2f}, 위치: {result['location']}{result['status']}")
  • 웹 접근성 색대비 체크를 위한 기능들을 호출합니다.

2. 결과 예시

웹 접근성 원본 이미지
웹 접근성 체크 후 이미지


감사합니다.

 


참고

반응형