이전에 썼던 코드는 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를 사용한 코드이며 출처는 다음과 같다.
글 잘 봤습니다.