AI 탐구노트

군중(Crowd) 카운팅 본문

DIY 테스트

군중(Crowd) 카운팅

42morrow 2024. 10. 29. 12:15

 

1. 개요

1.1. Crowd Counting이란?

Crowd counting은 이미지나 비디오를 분석해 특정 공간 내 인원 수를 세는 기술입니다. 군중 밀도가 높은 곳에서 안전 관리를 하거나, 공공 시설의 혼잡도를 예측하고, 마케팅 이벤트에서 방문자 수를 추적하는 데 유용합니다. 최근 딥러닝의 발전으로 인해, 더 정밀한 군중 수를 예측할 수 있게 되면서 다양한 실용적인 활용 사례가 늘고 있습니다.

 

1.2 활용 사례

Crowd Counting은 다음과 같은 다양한 분야에서 사용되고 있습니다. 

 

  • 스마트 시티 : 공공장소에서 실시간 인원 관리를 통해 안전과 편의를 증대
  • 대중교통 : 지하철역, 버스 정류장 등의 혼잡도를 분석하여 효율적인 운영 가능
  • 이벤트 관리 : 콘서트, 축제 등에서 군중의 밀도를 파악해 안전 문제 예방
  • 보안 및 감시 : 대규모 시위나 공공장소에서 이상 현상을 빠르게 탐지

 

 

2. 딥러닝 기반 Crowd Counting 개요

2.1. 기존 방법과 딥러닝 기반 접근법 비교

전통적인 기술은 주로 컴퓨터 비전과 머신러닝 기법을 활용해 객체 탐지 후 개체 수를 셉니다. 그러나 군중 밀도가 높을 때는 객체가 겹쳐 보여 정확도가 떨어지는 단점이 있습니다. 딥러닝 기반 접근법은 이미지에서 밀도 맵을 생성해 객체를 일일이 탐지하지 않고도 인원 수를 추정할 수 있어 더 높은 정확도를 보장합니다.

 

2.2. 딥러닝을 활용한 Crowd Counting의 기본 원리

딥러닝 기반 crowd counting은 주로 밀도 맵(Density Map*) 을 생성해 이미지 내의 군중 밀도를 시각화하고 이를 바탕으로 사람 수를 추정합니다. CNN(Convolutional Neural Network) 구조를 이용해 이미지의 패턴을 학습하고, 픽셀 단위로 밀도 값을 예측하여 군중 수를 계산하는 방법을 적용합니다. 

 

그 외에도 Object Detection 기반 방식과 Vision-Language Model를 기반으로 하는 방식 등이 있습니다. 각각 Yolo-Crowd와 CrowdCLIP 과 같은 모델들이 대표적인 예라고 할 수 있습니다. 

 

 

* 밀도맵 (Density Map)이란 이미지나 비디오 프레임에서 객체의 밀도를 표현하는 2차원 배열 형태의 출력으로, Crowd Counting에서는 각 픽셀에 사람이 존재할 확률을 나태내며 높은 값을 가진 부분일수록 더 많은 사람들이 밀집해 있다는 것을 의미합니다. 밀도맵의 모든 값을 환산하면 총 인원수를 추정할 수 있습니다. 기존의 방식은 모든 사람의 정확한 위치와 경계를 찾아야 하므로 복잡한 환경에서는 정확도가 떨어질 수 있습니다. 밀도맵을 이용하는 경우는 개체 별 경계를 구분하지 않으므로 더 높은 성능을 보일 수 있고 고밀도 군중 상황에서도 겹쳐 있는 객체들도 정확하게 수를 셀 수 있다는 장점이 있습니다. 

 

 

2.3. 주요 모델 개요

밀도맵 방식을 이용하는 대표적인 딥러닝 기반 모델로는 CSRNet, MCNN, CAN 등이 있습니다.

  • CSRNet은 기존의 CNN 구조에 dilated convolution을 추가해 밀도 예측의 정확도를 높였습니다.
  • MCNN(Multi-Column CNN)은 서로 다른 크기의 필터가 적용된 다중 컬럼 네트워크를 통해 다양한 군중 밀도를 파악합니다.
  • CAN(Context-Aware Network)은 이미지의 문맥 정보를 활용해 보다 정확한 예측을 수행합니다.

이번 테스트는 LWCC라는 Python용 경량 Crowd Counting 프레임워크를 이용합니다. LWCC는 CSRNet, DM-Count, SFANet, Baysian Crowd Counting의 4가지 모델을 지원합니다. 

 

3. 환경 구성

3.1. 요구 사항

테스트를 위해 다음과 같은 시스템 요구사항을 준비해야 합니다. 

  • 필요한 라이브러리 : Python, PyTorch, torchvision, Numpy 등
  • 소프트웨어 : Python 3.8 이상
  • 하드웨어 : GPU가 탑재된 시스템을 권장 (NVIDIA GPU와 CUDA 지원)

CUDA toolkit, cuDNN 등의 설치에 대한 설명은 건너 뛰겠습니다. 

 

3.2. 가상 환경 생성

 

 

$ conda create -n csrnet python=3.11
$ conda activate csrnet

 

 

3.3. lwcc 설치 

 

참고로 lwcc 설치시 dependency가 함께 설치되므로 설치 완료 후 바로 사용할 수 있습니다. 

$ pip install lwcc

 

 

3.4. 테스트 용 이미지 다운로드

아래 lwcc github repo에 올라온 2개의 이미지 파일을 테스트 용으로 사용합니다. (img01.jpg, img02.jpg)

 

lwcc/tests/dataset at master · tersekmatija/lwcc

LWCC: A LightWeight Crowd Counting library for Python that includes several pretrained state-of-the-art models. - tersekmatija/lwcc

github.com

 

두 개의 이미지 파일은 각각 아래와 같습니다. 

 

검증을 위해서는 미리 카운팅이 되어 있는 데이터셋에서 이미지와 카운팅 수 값을 미리 뽑아서 사용하시면 됩니다. 

 

 

4. Crowd Counting 실습

4.1. 코드

코드는 아주 단순합니다. 이미 lwcc 자체가 wrapper 역할을 하고 있기 때문입니다.  

from lwcc import LWCC

# 모델 초기화
model = LWCC.load_model(model_name = "DM-Count", model_weights = "SHB")

# 테스트 이미지 정의
img1 = 'data/img01.jpg'
img2 = 'data/img02.jpg'

# 이미지 카운팅만 하는 경우
count = LWCC.get_count([img1,img2], resize_img = True)

# 밀도맵도 함께 리턴받는 방법
count, density = LWCC.get_count([img1,img2], resize_img = True, return_density=True)

# 화면 가시화
import matplotlib.pyplot as plt
plt.imshow(density)
plt.show()

 

참고로 model 명을 바꿔주면  '~/.lwcc/weights' 폴더에 모델의 weight를 직접 다운로드합니다.

 

이미지를 멀티로 했을 때의 count, density의 데이터 형태는 다음과 같습니다. 

{'img01': np.float32(34.416668), 'img02': np.float32(425.34387)}
{'img01': array([[ 0.01138203,  0.01204397,  0.00982446, ..., -0.00071192,
         0.00474681,  0.00543051],
       [ 0.01574292,  0.02526549,  0.00794505, ...,  0.00231987,

 

4.2. 이미지 또는 비디오 입력으로 Crowd Counting 수행

이미지 입력으로 Crowd Counting을 수행한 결과는 다음과 같습니다. 

 

첫 이미지와 둘째 이미지에서 각각 27.230553과 414.40988의 값이 나왔습니다.

/home/sol/.lwcc/weights/DM-Count_SHB.pth
Built model DM-Count with weights SHB
{'img01': np.float32(27.230553), 'img02': np.float32(414.40988)}

 

4.3. 결과 시각화

밀도맵을 표시하는 방법도 간단합니다.

 

가시화하는 부분을 추가한 코드는 다음과 같습니다. 

 

import warnings
warnings.filterwarnings('ignore')

from lwcc import LWCC

# 모델 초기화
model = LWCC.load_model(model_name = "DM-Count", model_weights = "SHA")

# 테스트 이미지 정의
img1 = 'data/img01.jpg'
img2 = 'data/img02.jpg'

# 이미지 카운팅만 하는 경우
# count = LWCC.get_count([img1,img2], resize_img = True)

# 밀도맵도 함께 리턴받는 방법
count, density = LWCC.get_count([img1,img2], resize_img = True, return_density=True)

# 화면 가시화
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.colors import Normalize

from scipy.ndimage import zoom

org_img1 = plt.imread(img1)
density_map1 = density['img01']

zoom_factor = (
    org_img1.shape[0] / density_map1.shape[0], 
    org_img1.shape[1] / density_map1.shape[1]
)

# zoom 함수를 사용해 density map의 크기를 조정
resized_density_map = zoom(density_map1, zoom_factor, order=1)  # order=1은 bilinear interpolation

# 이미지 및 Density Map 가시화
fig, ax = plt.subplots()
ax.imshow(org_img1, cmap='gray')
ax.imshow(resized_density_map, cmap='jet', alpha=0.5, norm=Normalize(vmin=0, vmax=np.max(resized_density_map)))
ax.axis('off')
plt.show()

 

 

원본 이미지와 densityMap에 겹쳐 보면 다음과 같이 나오는데 제대로 counting을 한 것임을 알 수 있습니다. 

 

 

5. 후기

이번 글에서는 군중 카운팅을 손쉽게 할 수 있는 lwcc라는 도구를 이용해 봤습니다. 실제로 이것 내부에서는 여러가지 딥러닝 모델을 선택적으로 적용할 수 있도록 되어 있지만, 사용자의 편의를 위해 wraper 방식으로 사용할 수 있도록 한 것이라 보면 됩니다. (물론 그게 싫어서 직접 pytorch 등의 프레임워크 상에서 동작 시켜도 됩니다만 저는 활용할 수 있는 방안만 확인하는 주의라...) 

 

성능 상으로는 개선의 여지가 있을 것입니다. 하지만, 어느 정도 정확해야 하는가에 대한 기준은 적용할 장소와 카메라의 위치, 영상의 종류 등에 따라 전혀 다를 것이므로 그때의 환경에 맞추는 것이 맞다고 생각됩니다. 

 

Crowd Counting은 많은 사람들이 모이는 장소에서 혼잡도를 측정하거나 위험도를 판단할 때 활용하기 좋은 기술로 아마도 정부 기관에서는 시위, 모임, 행사 등에 많은 인원이 한번에 몰렸을 때의 위험을 실시간 감지하고 예방할 수 있는 도구로 이미 도입해서 사용하고 있을 것으로 생각됩니다. 찍힌 사진의 밀도맵을 통한 정적인 군중의 수에 대한 파악도 필요하겠지만 시간이 지나면서 그것이 어떻게 변화하는지를 보고 군중의 움직임 패턴을 파악하는 것도 중요할 것 같습니다. 또, 여기에서 사용된 밀도맵이라는 기술은 꼭 사람을 대상으로 하지 않아도 되므로, 동물, 물건 등 다수의 사물에 대한 대략적인 수량 파악 등 활용처가 많은 기술일 것 같습니다. 

 

다음 번에도 실생활에서 쓸만한 다른 것들을 테스트 해 보도록 하겠습니다. 

 


참고자료

 

1.YOLO-Crowd

 

Yolo-Crowd 모델은 Yolov5s를 기반으로 461개의 레이어를 얼굴 감지 기반 모델입니다. 엣지에서 동작 가능하다고 하며 얼굴 가려짐, 크기 변화 등 다양한 기존 과제를 해결한 모델이라고 합니다. 

 

 

 

GitHub - zaki1003/YOLO-CROWD: YOLO-CROWD is a lightweight crowd counting and face detection model that is based on Yolov5s and c

YOLO-CROWD is a lightweight crowd counting and face detection model that is based on Yolov5s and can run on edge devices, as well as fixing the problems of face occlusion, varying face scales, and ...

github.com

사진 : Yolo-Crowd를 이용한 적용 사례

 

 

 

2.CrowdCLIP 

 

Vision Language Model을 기반으로 한 Crowd Counting 모델로 2023년 CVPR에 게시된 모델입니다. 

 

 

GitHub - dk-liang/CrowdCLIP: [CVPR 2023] CrowdCLIP: Unsupervised Crowd Counting via Vision-Language Model

[CVPR 2023] CrowdCLIP: Unsupervised Crowd Counting via Vision-Language Model - GitHub - dk-liang/CrowdCLIP: [CVPR 2023] CrowdCLIP: Unsupervised Crowd Counting via Vision-Language Model

github.com

 

그림 : 모델 학습과 추론 Phase 설명

 

3.MSSRM

 

"Super-Resolution Information Enhancement For Crowd Counting" 논문의 구현체입니다. 아무래도 영상이나 이미지 상에서 많은 수의 군중에 대한 파악을 하기 위해서는 좀 더 명확한 이미지가 필요할테니 그런 경우에 SR 기술을 적용하는 것도 의미가 있다고 생각됩니다. 

 

 

GitHub - PRIS-CV/MSSRM: An implementation of MSSRM method

An implementation of MSSRM method. Contribute to PRIS-CV/MSSRM development by creating an account on GitHub.

github.com