본문 바로가기
Programming/Image Processing

[Image Processing][Python]이미지의 도심 구하기(Centroid)

by NoiB 2021. 12. 8.
반응형

이번엔 이미지의 도심을 구해보겠습니다. 저는 뭔가 이미지 선택을 좀 잘못한 것 같은데요. 여러분들은 확실하게 객체 구분이 되는 이미지를 사용하시면 좋을 것 같습니다.

결과 : 

코드 : 

import cv2
import numpy as np

def cvt_to_binary(img,binary_threshold):
    img1 = np.where(img > binary_threshold,255,img)
    img2 = np.where(img1 < binary_threshold,0,img1)
    return img2

def get_centroid(binary_img):
    h,w = binary_img.shape[:2]
    x=[]
    y=[]
    for i in range(h):
        for j in range(w):
            if binary_img[i][j] == 255:
                y.append(i)
                x.append(j)
    x_cen = sum(x)/len(x)
    y_cen = sum(y)/len(x)
    point = (x_cen,y_cen)
    return point

def draw_centroid(img,center_point):
    cv2.circle(img, center=tuple(np.int0(center_point)), radius=5, color=(255, 255, 0), thickness=4)

img = cv2.imread('./img_sample/img1.jpg',0)
binary_img = cvt_to_binary(img,90)
centroid = get_centroid(binary_img)
#print(centroid)
tmp = np.zeros((img.shape[0], img.shape[1], 3), dtype=np.uint8)
draw_centroid(img,centroid)

cv2.imwrite('./processed_img/img0_centroid.jpg', img)
cv2.imshow('img',img)
cv2.waitKey(0)
cv2.destroyAllWindows()

도심을 구하는 공식은 다음과 같습니다.

A는 도형의 면적입니다. 저는 어차피 이미지를 이진화 함으로써 값이 있는 위치의 전체 개수가 면적과 동일하기에 len(x)를 면적으로 잡았습니다(np.sum(binary_img)를 해도 됩니다만 모든 값이 255이므로 끝에 255를 나눠줘야 합니다). 그렇게 하고 각 좌표들을 더해서 면적으로 나누면 도심이 나오게 되겠죠. 나머지는 해당 도심을 이미지 위에 표시만 해주면 됩니다.

 

재밌게들 보고 계신가요? 누군가가 구현해놓은 기능을 함수 한 줄로 쓰다가 직접 해보려고 하니 막히는 부분이 종종 있습니다만 저는 상당히 재밌게 하고 있습니다. 다음 포스팅은 아마 스무딩 관련된 포스팅이 될 것 같습니다.

반응형