반응형
안녕하세요🐶
빈지식 채우기의 비니🙋🏻♂️ 입니다.
사내 AI 프로젝트를 진행하면서,
웹 접근성에 대해 공부할 기회가 생겼습니다. 바로 예시로 확인해보도록 하죠!

상기 이미지를 보면 알 수 있듯이,
푸른색 배경의 "안녕하세요" 는 가독성이 좋아서 보기 편합니다.
하지만 노란색 배경의 "안녕하세요" 는 무슨 글자인지 잘 보이지 않는데요.
이렇게 간단하게 색상 만으로 웹 접근성을 체크할 수 있습니다.
기존에는 작업자가 수작업으로 하나하나 체크를 했었습니다.
다만, 이러한 이미지가 100장...1000장....10000장이라면..?
너무나 많은 리소스가 투입될 것이고 작업 효율도 좋지 못할 것으로 생각됩니다.
하지만!!
만약 아래와 같은 프로세스를 가진 시스템이 있다면 어떨까요?.?
- 이미지 내의 객체를 찾는다.
- 찾은 객체의 색대비를 체크한다 ( WCAG 기준 )
- 웹 접근성 색대비에 부적합한 것을 이미지에 자동으로 표시한다.
딸깍딸깍 몇번으로 손 쉽게 웹 접근성 적합 유무를 파악할 수 있습니다.
그럼! 바로 소스를 통해 설명을 해드리겠습니다!
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. 결과 예시


감사합니다.
참고
반응형
'기타👨🏻💻 > AI' 카테고리의 다른 글
[AI] 이미지 웹 접근성 ( YOLO 모델 - 적용법과 간단 예제 ) (0) | 2025.02.28 |
---|---|
[AI] RAG 의 구성요소 2 ( Embedding ) (2) | 2024.09.04 |
[AI] 간단한 RAG 구현 ( Anaconda, Streamlit, OpenAI, Flask, Chroma, Hugging Face ) (7) | 2024.09.03 |
[AI] RAG 의 구성요소 1 ( Vector DB ) (0) | 2024.08.21 |
[AI] RAG ( Retrieval Augmented Generation ) 의 기초 (0) | 2024.08.20 |