[DIP] 직선을 원으로 변환하기 2

코드짜는침팬지·2023년 8월 3일
0

영상처리

목록 보기
3/4
post-thumbnail

이전에 썼던 코드는 2중 for문을 써서 연산속도가 오래 걸렸다.
파이썬의 특성을 이용하면 코드를 더욱 간결하고 빠르게 쓸 수 있는데
리스트를 통한 매핑을 사용하는 것 이다.

import numpy as np
import cv2
import matplotlib.pyplot as plt

def linear_polar(image):
    # Get the dimensions of the image
    height, width = image.shape[:2]

    # Create an empty output image
    polar_image = np.zeros((height*2, height*2), dtype=image.dtype)
    
    # Define the center
    center = np.array([height, height])

    # Create arrays to hold the Cartesian coordinates
    x, y = np.meshgrid(np.arange(height * 2), np.arange(height * 2))

    # Calculate the polar coordinates
    radius = np.sqrt((x - center[0])**2 + (y - center[1])**2).astype(int)
    theta = np.arctan2(y - center[1], x - center[0])

    # Map theta into the range of the image dimensions
    x1 = (((theta + np.pi) / np.pi) * ((height)/4) / 2).astype(int)

    # Apply the mappings
    valid_indices = (x1 >= 0) & (x1 < width) & (radius >= 0) & (radius < height)
    polar_image[valid_indices] = image[radius[valid_indices], x1[valid_indices]]

    return polar_image

src = ![](https://velog.velcdn.com/images/joongwon00/post/767a266d-7158-4045-883d-2e0d683a646c/image.png)
cv2.imread("C:/Users/joong/OneDrive/Documents/code_projects/RatelSoft/data2/Test_img/rotate2-3mm.BMP", cv2.IMREAD_GRAYSCALE)

lp = linear_polar(src)
cv2.imshow("lp", lp)
cv2.waitKey(0)
cv2.destroyAllWindows()

같은 결과물에 대해 이미지 사이즈에 따라 수천배 이상 빠른 결과를 출력할 수 있다.

만약 opencv에 있는 함수를 사용하고 싶다면 다음 코드를 사용하면 된다.

# 이미지 파일을 읽습니다.
import numpy as np
import cv2
# main window
WINDOW_NAME = "carToPol"
cv2.namedWindow(WINDOW_NAME)
# read input
src = cv2.imread("your image path")
# 이미지의 높이와 너비를 얻습니다.
h, w = src.shape[:2]
src = src[:, :int(w)]
# src = np.transpose(src, (1, 0, 2))
# src = np.flip(src, 1)

# get dimenions and compute half (for center/radius)
dims = src.shape[:-1]
cols,rows = dims
half = cols // 2

def carToPol(src,center,maxRadius,interpolation,rotate90=True):
    # rotate 90 degrees (cv2.warpAffine seems to mess up a column)
    if(rotate90):
        src = np.rot90(src)
    # cartesian to polar (WARP_INVERSE_MAP)
    return cv2.linearPolar(src,(centerX,centerY),maxRadius,interpolation + cv2.WARP_FILL_OUTLIERS + cv2.WARP_INVERSE_MAP)

# interpolation names: just for debugging
interpolations = ["NEAREST","LINEAR","CUBIC","AREA","LANCZOS4"]

# slider callbacks: just for debugging
def printCenterX(x):
    print("center",x)
def printCenterY(x):
    print("centerY",x)
def printMaxRadius(x):
    print("maxRadius",x)
def printInterpolation(x):
    global interpolations
    print("interpolation",interpolations[x])
# create sliders
cv2.createTrackbar("centerX"  ,WINDOW_NAME,half,cols,printCenterX)
cv2.createTrackbar("centerY"  ,WINDOW_NAME,half,cols,printCenterY)
cv2.createTrackbar("maxRadius",WINDOW_NAME,half,cols * 4,printMaxRadius)
cv2.createTrackbar("interpolation",WINDOW_NAME,cv2.INTER_CUBIC,cv2.INTER_LANCZOS4,printInterpolation)

# continously process for quick feedback
while 1:
    # exit on ESC key
    k = cv2.waitKey(1) & 0xFF
    if k == 27:
        break

    # read slider values
    centerX   = cv2.getTrackbarPos("centerX",WINDOW_NAME)
    centerY   = cv2.getTrackbarPos("centerY",WINDOW_NAME)
    maxRadius = cv2.getTrackbarPos("maxRadius",WINDOW_NAME)
    interpolation = cv2.getTrackbarPos("interpolation",WINDOW_NAME)

    dst = carToPol(src,(centerX,centerY),maxRadius,interpolation,True)
    # show result
    cv2.imshow(WINDOW_NAME,dst)
    # save image with 's' key
    if k == ord('s'):
        cv2.imwrite("output.png",dst)

# exit
cv2.destroyAllWindows()

opencv의 linear polar를 사용한 코드이며 출처는 다음과 같다.

https://stackoverflow.com/questions/55394160/question-about-how-to-convert-a-line-image-to-a-circle-image

profile
학과 꼴찌 공대 호소인

1개의 댓글

comment-user-thumbnail
2023년 8월 3일

글 잘 봤습니다.

답글 달기

관련 채용 정보