๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

AI/Computer Vision

[Computer Vision] Segmentation

728x90
๋ฐ˜์‘ํ˜•
๐Ÿ‘€ ๋ณธ ์˜ˆ์ œ๋Š” Window10์˜ VSCode, Python3.11.0๋กœ ์ž‘์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

 

Segmentation์€ ์˜์ƒ์—์„œ ํŠน์ • ์˜์—ญ๋งŒ ์ถ”์ถœํ•˜๋Š” ๊ธฐ๋Šฅ์ด๋‹ค. 

์˜ˆ๋ฅผ ๋“ค์–ด ์˜๋ฃŒ ์˜์ƒ์—์„œ ์ข…์–‘์„ ์‹๋ณ„ํ•˜๊ฑฐ๋‚˜, ์ž์œจ์ฃผํ–‰์ฐจ๊ฐ€ ๋„๋กœ์™€ ๋ณดํ–‰์ž๋ฅผ ๊ตฌ๋ถ„ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋œ๋‹ค.

 

OpenCV์—์„œ๋Š” K-Means ๋˜๋Š” Watershed ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ํ†ตํ•ด Segmentation์„ ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

K-Means

K-Means ํด๋Ÿฌ์Šคํ„ฐ๋ง์€ ๋จธ์‹ ๋Ÿฌ๋‹ ์ค‘ ํ•˜๋‚˜๋กœ ๋น„์ง€๋„ ํ•™์Šต ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋‹ค.

๋ฐ์ดํ„ฐ๋ฅผ K๊ฐœ์˜ ํด๋Ÿฌ์Šคํ„ฐ๋กœ ๋‚˜๋ˆ„๋Š” ๊ธฐ๋ฒ•์œผ๋กœ ์ด๋ฅผ ํ†ตํ•ด ์ด๋ฏธ์ง€๋ฅผ ์ƒ‰์ƒ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ถ„ํ•  ํ•  ์ˆ˜ ์žˆ๋‹ค.

import cv2
import numpy as np
import random

if __name__ == "__main__":
    img = cv2.imread("cat.png")
    # Resize
    h,w,c = img.shape
    img = cv2.resize(img,(int(w//2),int(h//2)))
    cv2.imshow("original",img)

    # BGR to RGB
    img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
    # ์ด๋ฏธ์ง€๋ฅผ 2D ๋ฐฐ์—ด๋กœ ๋ณ€ํ™˜
    pixel_values = img.reshape((-1,3))
    pixel_values = np.float32(pixel_values)
    # k-means
    k = 2
    criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 100,0.2)
    # Radom์œผ๋กœ ์ค‘์•™ ์„ค์ •
    _,labels,centers = cv2.kmeans(pixel_values,k,None,criteria,10,cv2.KMEANS_RANDOM_CENTERS)

    # ๊ฐ ํด๋Ÿฌ์Šคํ„ฐ์— ๋Œ€ํ•ด ๋žœ๋ค ์ƒ‰์ƒ ์ƒ์„ฑ
    colors = []
    for _ in range(k):
        colors.append([random.randint(0, 255) for _ in range(3)])

    # ์„ธ๊ทธ๋ฉ˜ํ…Œ์ด์…˜๋œ ์ด๋ฏธ์ง€๋ฅผ ์ƒ‰์ƒ์œผ๋กœ ์ฑ„์šฐ๊ธฐ
    segmented_img = np.zeros_like(img)
    for i in range(len(labels)):
        segmented_img[i // img.shape[1], i % img.shape[1]] = colors[labels[i][0]]

    cv2.imshow("segmentation",segmented_img)

    cv2.waitKey(0)
    cv2.destroyAllWindows()

 

 

Watershed

Watershed๋Š” ์ด๋ฏธ์ง€ ๋‚ด ๊ฒฝ๊ณ„์„ ์„ ์ฐพ๊ณ  ์ด๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๊ฐ์ฒด๋ฅผ ๋ถ„ํ• ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

์ด ๋ฐฉ๋ฒ•์€ ๋ณต์žกํ•œ ๋ฐฐ๊ฒฝ ์†์—์„œ ๊ฐ์ฒด๋ฅผ ์‹๋ณ„ํ•˜๋Š” ๋ฐ ์œ ์šฉํ•˜๋‹ค.

import cv2
import numpy as np
import random

if __name__ == "__main__":
    image = cv2.imread("coin.jpg")
    # Resize
    cv2.imshow("original",image)

    # ์ด๋ฏธ์ง€ ์ „์ฒ˜๋ฆฌ
    gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)

    ret, thresh = cv2.threshold(gray,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)

    # noise removal
    kernel = np.ones((3,3),np.uint8)
    opening = cv2.morphologyEx(thresh,cv2.MORPH_OPEN,kernel, iterations = 2)
    
    # sure background area
    sure_bg = cv2.dilate(opening,kernel,iterations=3)
    
    # Finding sure foreground area
    dist_transform = cv2.distanceTransform(opening,cv2.DIST_L2,5)
    ret, sure_fg = cv2.threshold(dist_transform,0.7*dist_transform.max(),255,0)
    
    # Finding unknown region
    sure_fg = np.uint8(sure_fg)
    unknown = cv2.subtract(sure_bg,sure_fg)
    cv2.imshow("Dist",dist_transform)
    cv2.imshow("watershed",sure_fg)

    # Marker labelling
    ret, markers = cv2.connectedComponents(sure_fg)
    
    # Add one to all labels so that sure background is not 0, but 1
    markers = markers+1
    
    # Now, mark the region of unknown with zero
    markers[unknown==255] = 0

    markers = cv2.watershed(image,markers)
    image[markers == -1] = [255,0,0]
    cv2.imshow("segmentation",image)

    cv2.waitKey(0)
    cv2.destroyAllWindows()

 

 

์ด๋Ÿฌํ•œ ๋ฐฉ๋ฒ• ๋ง๊ณ ๋„ ๋”ฅ๋Ÿฌ๋‹์„ ์‚ฌ์šฉํ•œ Segmentation(UNet)๋„ ์žˆ๋‹ค.

์ด ๋ฐฉ๋ฒ•์ด ํ•™์Šต๋งŒ ์ถฉ๋ถ„ํžˆ ๋œ๋‹ค๋ฉด ๋” ์„ฌ์„ธํ•˜๋‹ค.

 

SAM2 Image Predictor - a Hugging Face Space by fffiloni

 

huggingface.co

 

728x90
๋ฐ˜์‘ํ˜•