본문 바로가기
개발/openCV

[openCV] fingerprint equalization, binarization, morphology, smoothing, skeletonization

by meanjung 2022. 3. 29.

평탄화(Equlaization)

명암 대비를 높이기 위함 

검은 곳은 더 검게, 밝은 곳은 더 밝게

https://opencv-python.readthedocs.io/en/latest/doc/20.imageHistogramEqualization/imageHistogramEqualization.html

 

히스토그램 균일화 — gramman 0.1 documentation

CLAHE (Contrast Limited Adaptive Histogram Equalization) 지금까지의 처리는 이미지의 전체적인 부분에 균일화를 적용하였습니다. 하지만 일반적인 이미지는 밝은 부분과 어두운 부분이 섞여 있기 때문에 전

opencv-python.readthedocs.io

  • equalizeHist 함수
    • 전체적으로 밝아지기는 하지만 밝은 부분이 너무 밝아진다.
  • CLAHE
    • CLAHE를 위해 구분한 일정한 크기를 가진 작은 블록 : 타일
      • openCV에서 타일 크기는 디폴트로 8x8이다.
    • 밝은 부분의 윤곽선도 유지가 되면서 전체적인 contrast가 높아진다.
    • 이미지에 노이즈가 있는 경우 타일 단위의 히스토그램 균일화를 적용하면 노이즈가 커질 수 있는데, CLAHE 알고리즘은 이런 노이즈를 감쇠시키는 Contrast Limiting이라는 기법을 사용한다.
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
img_cl = clahe.apply(img_gauss)

이진화(binarization)

어떤 threshold를 기준으로 0(검), 255(흰)으로 이진화한다. 

  • otsu 알고리즘
    • 임계값을 임의로 정해 픽셀을 두 부류로 나누고 두 부류의 명암 분포를 구하는 작업을 반복한다.
    • 최적의 임계값을 자동으로 찾아준다. 
    • 이 코드에서는
      • 구역을 나눠서 otsu 이진화를 적용했다. 여러 개의 임계값을 이용하게 된다. 

img_dst = np.zeros(img_gray.shape, np.uint8) # 검정색 영상

img_size = img_gray.shape[0]
window_size = 7

y= 0
while True:
  y_start = window_size*y
  y_end = window_size*(y+1)
  if y_end>img_size:
    y_end = img_size
  x=0
  while True:
    x_start = window_size*x
    x_end = window_size*(x+1)
    if x_end>img_size:
      x_end = img_size
    src_ = img_gray[y_start:y_end, x_start:x_end]
    # dst_ = img_dst[y_start:y_end, x_start:x_end]
    t, dst_ = cv2.threshold(src_, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
    img_dst[y_start:y_end, x_start:x_end] = dst_
    if x_end==img_size:
      break
    x+=1
  if y_end==img_size:
    break
  y+=1

img_otsu = 255 - img_dst
  • 적응형 스레시홀딩
    • 하나의 임계값으로 선명한 바이너리 이미지를 만들어내기 힘들 수 있다. 
    • 이때 이미지를 여러 영역으로 나눈 뒤, 그 주변 픽셀 값만을 활용하여 임계값을 구할 수 있다. 
    • 이미지를 blockSize 등분해서 블록별로 임계값을 정한다.

    • cv2.ADAPTIVE_THRESH_MEAN_C: 이웃 픽셀의 평균으로 결정
      • 가우시안 분포를 활용한 것보다 더 선명한데 그만큼 잡티가 더 있다.
    • cv2.ADAPTIVE_THRESH_GAUSSIAN_C: 가우시안 분포에 따른 가중치의 합으로 결정
      • 평균값을 활용한 것에 비해 선명도는 조금 떨어지지만 잡티가 적다.
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img_at = cv2.adaptiveThreshold(img_gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 15, 5)

plt.imshow(img_at, cmap='gray')

노이즈 제거(morphology)

  • morphology 연산은 검/흰으로만 구성된 바이너리 이미지에 적용할 수 있다.
    • erode
      • 한 픽셀이라도 검 -> 검 변환
      • 검은색(배경)이 많아지고, 흰색(관심객체)이 줄어든다. 
      • 검은 배경에 흰색 점을 지우려면
    • dilate
      • 한 픽셀이라도 흰 -> 흰 변환
      • 검은색(배경)이 줄어들고, 흰색(관심객체)이 많아진다.
      • 흰색 내부에 검은 점을 지우려면
    • open
      • erode -> dilate
      • 맞닿아있는 것처럼 보이는 개체 분리에 효과적 & 돌출된 모양 제거
      • 주변보다 밝은 노이즈 제거
      • 관심객체가 연결돼있으면 끊어준다.
    • close
      • dilate -> open
      • 끊어져보이는 개체 연결하거나 구멍을 메우는 데 효과적
      • 주변보다 어두운 노이즈 제거
      • 관심객체가 끊어져있으면 연결해준다.

smoothing

블러링을 적용하면 이미지는 흐릿해지지만 흑/백 영상일 때 노이즈를 제거하는데 유용한 방법.

이미지를 좀 더 매끈하게 보이도록 할 수 있다.

이진화 전, 후에 모두 사용할 수 있다.(내가 그렇게 사용했다.)

  • Average Blurring
    • cv2.blur 함수
    • 박스 크기를 지정하고, 그 안의 픽셀값들의 평균으로 현재 픽셀값을 대체한다.
  • Gaussian Blurring
    • 2차원 가우시안 분포를 이용해 블러링한다.
      • 박스 내에 픽셀값을 가우시안 분포의 가중치로 평균내어 현재 픽셀값을 업데이트 해준다.
      • 이 가중치는 중심 픽셀에서 멀어질수록 급격하게 줄어든다.
      • 따라서 중심 픽셀의 값은 그 바로 주변의 픽셀들의 영향을 가장 크게 받게 된다.

img_gauss = cv2.GaussianBlur(img_gray, (3, 3), 0)
  • Median Blurring
    • 현재 픽셀값을 박스내의 픽셀값들의 중간값으로 대체한다.
img_res = cv2.medianBlur(img_res, 3)
  • Bilateral Blurring
    • 위의 세 방법과 마찬가지로 노이즈를 제거하지만 이미지 내의 edge는 살리는 방식


세선화(skeletonization)

처음엔 검색해서 나온대로 직접 세선화하려고 했는데 결과값이 영 좋지 않았다...

그래서 막 구글링하다가 찾은...

pip install opencv-contrib-python

img_thinned = cv2.ximgproc.thinning(img)
plt.imshow(img_thinned, cmap='gray')

직접 구현은 다음 블로그 참고

https://medium.com/analytics-vidhya/skeletonization-in-python-using-opencv-b7fa16867331

 

Skeletonization in Python using OpenCV

Let me start off with a (not so) funny joke.

medium.com

 


참고

https://bkshin.tistory.com/entry/OpenCV-8-%EC%8A%A4%EB%A0%88%EC%8B%9C%ED%99%80%EB%94%A9Thresholding

 

OpenCV - 8. 스레시홀딩(Thresholding), 오츠의 알고리즘(Otsu's Method)

이번 포스팅에서는 바이너리 이미지를 만드는 대표적인 방법인 스레시홀딩에 대해 알아보겠습니다. 이번 포스팅 역시 '파이썬으로 만드는 OpenCV 프로젝트(이세우 저)'를 정리한 것임을 밝힙니다

bkshin.tistory.com

https://deep-learning-study.tistory.com/225

 

[파이썬 OpenCV] 이진 영상 처리 - 지역 이진화 - cv2.adaptiveThreshold

황선규 박사님의 'OpenCV 4로 배우는 컴퓨터 비전과 머신 러닝' 을 공부하면서 정리해 보았습니다. 예제 코드 출처 :  황선규 박사님 github홈페이지 『OpenCV 4로 배우는 컴퓨터 비전과 머신 러닝』

deep-learning-study.tistory.com

https://gmnam.tistory.com/160

 

[OpenCV] 이미지 blurring (smoothing) 처리

[OpenCV] 이미지 blurring (smoothing) 처리 이미지 블러링은 이미지 처리나 컴퓨터 비전에 사용되는 기본적인 이미지 변형 방법이다. 이것은 이미지에 필터의 합성(2D convolution)을 통해 이뤄진다. 즉, 원

gmnam.tistory.com

https://deep-learning-study.tistory.com/144

 

[파이썬 OpenCV] 영상에 블러링(가우시안 필터) 적용하기 - cv2.GaussianBlur

황선규 박사님의 , OpenCV 강의를 공부한 내용을 정리했습니다. 영상에 블러링(가우시안 필터) 적용하기 - cv2.GaussianBlur  이전 포스팅에서 평균값 필터 블러링에 대해 알아보았습니다.  평균값 필

deep-learning-study.tistory.com

 

댓글