본문 바로가기

졸업프로젝트/OpenCV

[OpenCV] 이미지 이진화

728x90

 

 

이미지 불러오기

def contour():
    #이미지
    imgfile = '/gdrive/MyDrive/cropStudy/problem.png'

    #원본 이미지
    img = cv2.imread(imgfile)

 

 

 

이미지를 흑백으로 만들기

이미지를 흑백으로 만들어주면 연산량이 적고, 흑백이미지도 edge detection에 무리 없기 때문에 진행하는 과정 

 

cvtColor : 이미지의 색 변경

    #흑백 이미지
    imgray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

 

cvtColor : 이미지의 색을 변경해주는 함수 
cvtColor(image : 변경할 이미지 파일 경로 , flag : 어떤방식으로 변경할지 ) 

정확하게 말하면, 이미지의 색 공간을 바꾸는 함수이며 flag는 어떤 색 공간으로 바꿀지 결정한다.

예) flag = COLOR_BGR2GRAY : 이미지를 BGR영역(OpenCV는 RGB대신 BGR을 사용) 에서 GRAY영역으로 변경함

 

Color Space

각각의  색공간은 각자의 장점을 가진다. 

이미지의 사용 용도에 맞게 색공간을 변경하여 사용하기 때문에 여러 색공간사이의 변형이 필요하다 

RGB : 이미지를 저장하고 불러올 때 주로 사용

Red / Green / Blue 

 

HSV : 특정한 색 영역을 추출해 낼때 용이한 색 공간 

Hue(색상) : 스펙트럼을 기준으로 고리모양으로 360도 펼쳐놓은모양 (0도가 빨강)

Saturation(채도) : 특정 색상에서 가장 진한 상태를 100%

Value(명도)

 

그 외에도 GRAY, YCrCb, Luv등의 색 공간이 있다. 

 

결과 참고)

blog.naver.com/PostView.nhn?blogId=alsrb968&logNo=220909428222&redirect=Dlog&widgetTypeCall=true&directAccess=false

 

OpenCV : 컬러 변환 cvtColor 함수

이번엔 cvtColor함수를 이용해서 기본 BGR의 컬러를 GRAY COLOR_BGR2GRAY, COLOR...

blog.naver.com

 

* imread 에서 gray로 변경하지 않고 cvtColor를 사용한 이유 

  • edge detection에서 원본 이미지를 사용하면, 원본이미지가 변형되므로 미리 원본을 백업하는 용도
  • 마지막에 원본 이미지 위에 edge를 그리기 위해서 

 

flag 참고

docs.opencv.org/3.4/d8/d01/group__imgproc__color__conversions.html

 

OpenCV: Color Space Conversions

enum  cv::ColorConversionCodes {   cv::COLOR_BGR2BGRA = 0,   cv::COLOR_RGB2RGBA = COLOR_BGR2BGRA,   cv::COLOR_BGRA2BGR = 1,   cv::COLOR_RGBA2RGB = COLOR_BGRA2BGR,   cv::COLOR_BGR2RGBA = 2,   cv::COLOR_RGB2BGRA = COLOR_BGR2RGBA,   cv::COLOR_R

docs.opencv.org

 

코드)

def contour():
    #이미지
    imgfile = '/gdrive/MyDrive/cropStudy/problem.png'

    #원본 이미지
    img = cv2.imread(imgfile)

    #흑백 이미지
    imgray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) #원본 이미지와 흑백이미지가 따로 존재

 

결과)

RGB색공간을 GRAY색공간으로 변경 

 

외곽을 검출하기

외곽을 검출하기 전에 검출하기를 원하는 부분은 문제부분이기 때문에

뒤에 EBSi로고 부분은 외곽으로 검출되지 않아야한다. 

그를 위해서는 배경에 blur효과를 준다.

 

1. 배경 흐리기 + 이미지 이진화

 

GaussianBlur : 이미지에 블러처리를 해주는 함수 
cv2.GaussianBlur(image : 블러처리를 원하는 이미지 경로, ksize=(n,n) : 블러 커널 사이즈, sigmaX=0 )

커널사이즈를 적당히 조절하여, 이미지를 블러처리한다.

너무 강하게 블러를 주면 외곽을 잘 찾아낼 수 없고, 너무 약하게 주면 원하지 않는 배경까지 외곽으로 검출된다.

 

threshold : 이미지 이진화

*이진화 : 이미지를 흑/백으로 분류하여 처리하는 방법으로 임계값보다 크면 white, 작으면 black이 된다(TRHESH_BINARY). 

threshold(image : 적용할 이미지 , thresh : 임계값, maxval : 임계값이 넘었을 때 사용할 값, flag )

 

 

flag

적용 결과)

 

코드)

def contour():
    #이미지
    imgfile = '/gdrive/MyDrive/cropStudy/problem.png'

    #원본 이미지
    img = cv2.imread(imgfile)

    #흑백 이미지
    imgray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) #원본 이미지와 흑백이미지가 따로 존재

	#배경 흐리기
    blur = cv2.GaussianBlur(imgray, ksize=(3,3), sigmaX=0)
    
    #이미지 이진화
    ret, thresh1 = cv2.threshold(blur, 127, 255, cv2.THRESH_BINARY)

**이진화시 임계치를 127(0 + 255 / 2)로 설정 

 

결과)

이미지 blur처리

 

이미지 이진화

임계치를 127로 설정하여, 01 02 등에 숫자 0이 사라짐 -> 나중에 필요하면 살리고... 

 

+추가)

Otsu's Threshold

임계치를 자동으로 계산하기 

임계치를 사용자가 정하는 것 보다는 bimodal image를 이용하여 적절한 임계치를 어느정도 정확하게 계산해 낼 수 있음

flag 부분에 cv2.TRHESH_STSU를 적용하면됨

 

otsu미사용 / otsu사용 / blur처리 후 otsu사용 

블러 처리를 한 후 otsu를 하는 것이 가장 효과적

 

코드)

def contour():
    #이미지
    imgfile = '/gdrive/MyDrive/cropStudy/problem.png'

    #원본 이미지
    img = cv2.imread(imgfile)

    #흑백 이미지
    imgray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) #원본 이미지와 흑백이미지가 따로 존재

	#이미지 이진화(TRESH_TOSU)
    ret, thresh1 = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)

 

결과)

 

 

 

 

 

 

 

참고사이트

threshold 

opencv-python.readthedocs.io/en/latest/doc/09.imageThresholding/imageThresholding.html

 

이미지 임계처리 — gramman 0.1 documentation

기본 임계처리 이진화 처리는 간단하지만, 쉽지 않은 문제를 가지고 있다. 이진화란 영상을 흑/백으로 분류하여 처리하는 것을 말합니다. 이때 기준이 되는 임계값을 어떻게 결정할 것인지가 중

opencv-python.readthedocs.io

 

728x90