在Python、OpenCV中将对象映射到圆
给定一个包含分割对象的灰度图像的numpy数组。numpy数组具有维度在Python、OpenCV中将对象映射到圆,python,opencv,Python,Opencv,给定一个包含分割对象的灰度图像的numpy数组。numpy数组具有维度(32,32)。该对象的背景编码为零,对象本身有一个介于(0255)之间的数字。 示例(尺寸(7,7)): #输入 >np.数组([[0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0],[0,0,1,2,3,0,0],[0,0,2,2,0,0,0],[0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0],[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0]
(32,32)
。该对象的背景编码为零,对象本身有一个介于(0255)之间的数字。
示例(尺寸(7,7)
):
#输入
>np.数组([[0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0],[0,0,1,2,3,0,0],[0,0,2,2,0,0,0],[0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0],[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0],[0,0,
数组([[0,0,0,0,0,0,0,0],
[0, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 2, 3, 0, 0],
[0, 0, 2, 2, 2, 0, 0],
[0, 0, 1, 2, 3, 0, 0],
[0, 0, 0, 0, 0, 0, 0],
[0,0,0,0,0,0,0]],dtype=uint8)
numpy数组中的对象可以具有任意形状。
我希望拉伸(扭曲)对象,使其成为一个圆,而不管其先前的形状如何。该圆应填充整个32x32数组。值应进行线性插值。
示例(简化,无线性插值):
#所需输出=带线性插值的圆
数组([[0,0,0,2,0,0,0,0],
[0, 1, 1, 2, 3, 3, 0],
[0, 1, 1, 2, 3, 3, 0],
[2, 2, 2, 2, 2, 2, 2],
[0, 1, 2, 2, 3, 3, 0],
[0, 1, 2, 2, 3, 3, 0],
[0,0,0,2,0,0,0]],dtype=uint8)
我该怎么做。是否有一个OpenCV函数可以将对象扭曲成圆?让我们将问题分为三个步骤:
square = np.array([[0,0,0,0,0,0,0],[0,0,0,0,0,0,0],[0,0,1,2,3,0,0],[0,0,2,2,2,0,0],[0,0,1,2,3,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,0,0]], dtype=np.uint8)
resized_image = cv2.resize(square, (32, 32))
将矩阵从正方形重新映射到圆形
从数学上讲,有很多方法可以创建从方阵到圆的变换。这是一个非常有趣的话题。基本上,你必须定义一个函数,从一组点[x,y]
到另一组点[u,v]
,方志伟提到的一个可能的解决方案是:
u=x√(x²+y²-x²y²)/√(x²+y²)
v=y√(x²+y²-x²y²)/√(x²+y²)
您可以使用此公式和函数来获得所需的转换。但是有一个名为的工具可以为您完成所有工作!通过阅读他们的文档,您可以生成一个简单的代码来进行此转换:
导入时使用:
from squircle import to_circle
from PIL import Image
打开图像后调用转换:
circle = to_circle(square)
必要时修剪边缘并调整大小
现在,您只需修剪矩阵中的所有零,然后重新调整其大小,使所有32x32矩阵中都包含内容。您可以使用的解决方案如下所述:circle
是重新映射的图像。在剪切所有初始行和最终行以及列后,您必须再次将其调整为32x32
coords = np.argwhere(circle)
x_min, y_min = coords.min(axis=0)
x_max, y_max = coords.max(axis=0)
b = cropped = circle[x_min:x_max+1, y_min:y_max+1]
resized_cropped_image = cv2.resize(cropped, (32, 32))
完整示例
示例1-使用数组:
示例2-使用另一个图像: 你可以在我的Github页面上找到。完整的代码可以在下面看到
import numpy as np
import cv2
import matplotlib.pyplot as plt
from squircle import to_circle, to_square
from PIL import Image
square = np.asarray(Image.open('Picture.png').convert('L'))
#square = np.array([[0,0,0,0,0,0,0],[0,0,0,0,0,0,0],[0,0,1,2,3,0,0],[0,0,2,2,2,0,0],[0,0,1,2,3,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,0,0]], dtype=np.uint8)
resized_image = cv2.resize(square, (32, 32))
circle = to_circle(resized_image)
coords = np.argwhere(circle)
x_min, y_min = coords.min(axis=0)
x_max, y_max = coords.max(axis=0)
b = cropped = circle[x_min:x_max+1, y_min:y_max+1]
resized_cropped_image = cv2.resize(cropped, (32, 32))
fig, axs = plt.subplots(2, 2, figsize=(10,10))
axs[0, 0].imshow(square)
axs[0, 0].set_title('Original')
axs[0, 1].imshow(resized_image)
axs[0, 1].set_title('Resized to 32x32')
axs[1, 0].imshow(circle)
axs[1, 0].set_title('Remapped to cicle')
axs[1, 1].imshow(resized_cropped_image)
axs[1, 1].set_title('Trimmed')