Privacy Masking
요약 : Image segmentation 기술로 Privacy를 보호
기간 : ~ 2022년 09월 (재직 마지막까지 진행)
언어: C/C++
개발환경 및 기술 : Linux, docker
시연 영상
https://www.youtube.com/watch?v=uUmOhEZkDOo
https://www.youtube.com/watch?v=bFuMzfEzFyk
Yolact segmentation 기반으로 사람 부분을 가려서 privacy를 보호.
Yolo 기반 head detect을 추가로 적용하여 얼굴은 더욱 보호.
단색 마스킹
image segmentation기술을 이용해서 사람 부분을 검은 색으로 변환.
blur
마찬가지로 사람 부분을 변환. 적당한 convolution 연산으로 이미지를 흐리게 함.
모자이크
1. convolution을 사용. kernel size가 모자이크 크기가 되고, kernel size와 stride값이 같으면 모자이크 구현가능.
2. image resize사용. 이미지 크기를 줄였다가 다시 늘리면 모자이크 구현 가능.
문제 해결
프레임중 Privacy를 보호하기 위한 masking이 풀리는 문제
안풀리는 프레임들의 masking들을 합쳐서 방지.
계단현상
pixel wise confidence가 0과 1로 양자화되어 발생한 문제. pixel wise confidence로 이루어진 tensor를 resize해서 사용.
(코로나 당시) 마스크 쓴 사람에서 성능 떨어지는 문제
실시간 webcam 영상 파일로 저장(학습 데이터 생성용)하고, 다른 사진에서 잘라낸 사람과 임의의 배경과 합성해서 data augmentation을 통해 마스크 쓴 사람 추가로 데이터 보강.
ONNX export
학습한 python 모델을 카메라에 그대로 올릴 수 없어서, 변환이 지원되는 연산과 아닌 연산을 갈라 두 갈래로 내보냈습니다. 초록 테두리가 ONNX 로 나간 구간, 주황 테두리가 개발보드에서 C++ 로 다시 쓴 구간입니다.
flowchart TD
Y["YOLACT · PyTorch 학습 모델"] --> S{"이 연산이 파일 변환을 지원하는가"}
S -->|"지원"| A1["backbone · protonet"]
S -->|"지원"| A2["linear combination · masking"]
S -->|"지원"| A3["blur · 모자이크 — torchvision 대신 conv kernel 에 weight 를 직접 넣어 구현"]
S -->|"미지원"| B1[["box decode"]]
S -->|"미지원"| B2[["detection module"]]
A1 --> O["ONNX export"]
A2 --> O
A3 --> O
O --> M["AI 카메라 전용 모델로 한 번 더 변환"]
B1 --> C["개발보드에서 C++ 로 직접 구현"]
B2 --> C
M --> R["개발보드 런타임 — 전용 모델 + C++ 구간"]
C --> R
R --> F["마스킹된 프레임"]
O -.->|"같은 입력에 같은 출력인지 대조"| M
classDef conv stroke:#16a34a,stroke-width:2px
classDef cpp stroke:#ea580c,stroke-width:2px
class A1,A2,A3,O,M conv
class B1,B2,C cpppython model -> (python)onnx model -> (C++)AI 카메라 전용 모델로 변환
변환을 지원하는 부분과 아닌 부분을 분리.
yolact에서 box decode와 detection module등은 개발보드에서 C++ code로 구현.
yolact에서 linear combination부분과 masking부분을 python으로 구현된 부분을 잘라서 onnx로 만들고 AI 카메라용으로 한 번 더 변환.
convolution으로 구현한 blur나 모자이크도 onnx export->AI카메라 전용 모델로 변환.
blur기능은 torchvision에 있으나 카메라에 올리기 위해서는 파일 변환이 필요하고, blur기능은 파일 변환이 지원되지 않아서 직접 convolution kernel에 weight를 집어넣어서 구현.
“AI 카메라용 개발보드에 포팅하기 위해 onnx에서 변환시킨 파일”이 onnx와 똑같이 작동하는지 테스트
yolact 학습 class 조정 (81 ->2)
사람과 배경 두 가지 class만 남겨서 용량을 줄임.
backbone 변경.
resnet 101, 50, darknet 53 등 여러 backbone test.
darknet 53은 pc에서 빠르나 개발보드에서는 resnet101보다 느림
resolution을 보관하고 있는 buffer를 이용해서 resize코드를 제거.
여러 memcpy 코드를 제거하고 같은 메모리 영역을 사용하게 변경.
모델 양자화 (32 bit -> 16 bit, 32 bit -> 8 bit)
속도 및 용량 과 성능 trade off
코드에서 GPU부분과 CPU부분을 multi thread로 처리
GPU가 도는 동안 CPU가 비어있지 않게 최대한 자원을 활용하여 실행
기술적으로 어려웠던 경험
python
용량 문제 : GPU memory out, 학습 중 큰 용량 처리 못해서 생긴 학습 오류 sigkill.
학습 중 CUDA error로 멈추는 현상.
개발 보드(C++)
펌웨어 업데이트 시 잘 되던 코드가 안되는 현상.
Logger가 static변수보다 늦게 생성.
logger를 찍을수 없는 시점이 있지만 디버깅은 해야하는 상황 경험.
모델 변환을 지원하지 않는 경우나 포팅이 안되는 라이브러리 및 함수 직접 구현 필요.
배운점/얻은 것
실전 linux 환경 개발 경험.
개발 보드 환경에서 개발을 위해 docker 활용 경험.
onnx 활용 경험. ioctl의 이해와 활용,
fd(file descriptor)에 대한 이해 확장
내부 여러 device를 fd로 관리하며 활용하는 방법.
변환을 지원하지 않는 함수들 C++ 코드로 직접 작성해보는 경험