python - 把圆形变成方形。已解决:松鼠包
问题描述
OpenCV / Python相关:
给定一张圆形物体的照片,如何在调整表面积的同时输出扁平的物体?这是输入的示例图像:
它类似于调整相机失真(将圆形物体变成扁平物体),但在这种情况下,失真来自物体本身而不是相机。
任何建议都会有所帮助。谢谢!
编辑: squircle 包正是我所需要的,谢谢 fmw42!
解决方案
这是 Python/OpenCV 中的解决方案。它创建转换映射,定义从输出返回到输入的方程,并使用 cv2.remap() 应用它们。这些方程来自https://arxiv.org/pdf/1509.06344.pdf用于椭圆网格映射方法。
输入:
import numpy as np
import cv2
import math
# References:
# https://arxiv.org/pdf/1509.06344.pdf
# http://squircular.blogspot.com/2015/09/mapping-circle-to-square.html
# Evaluate:
# u = x*sqrt(1-y**2/2)
# v = y*sqrt(1-x**2/2)
# u,v are input circle coordinates and x,y are output square coordinates
# read input
img = cv2.imread("rings.png")
# get dimensions and center
h, w = img.shape[:2]
xcent = w / 2
ycent = h / 2
# set up the maps as float32 from output square (x,y) to input circle (u,v)
map_u = np.zeros((h, w), np.float32)
map_v = np.zeros((h, w), np.float32)
# create u and v maps where x,y is measured from the center and scaled from -1 to 1
for y in range(h):
Y = (y - ycent)/ycent
for x in range(w):
X = (x - xcent)/xcent
map_u[y, x] = xcent * X * math.sqrt(1 - 0.5*Y**2) + xcent
map_v[y, x] = ycent * Y * math.sqrt(1 - 0.5*X**2) + ycent
# do the remap
result = cv2.remap(img, map_u, map_v, cv2.INTER_LINEAR, borderMode = cv2.BORDER_REFLECT_101, borderValue=(0,0,0))
# save results
cv2.imwrite("rings_circle2square.png", result)
# display images
cv2.imshow('img', img)
cv2.imshow('result', result)
cv2.waitKey(0)
cv2.destroyAllWindows()
结果:
这是另一个例子:
输入:
结果:
这是第三个例子:
输入:
结果:
添加
这是基于上述参考中的简单拉伸方程的替代方法:
import numpy as np
import cv2
import math
# References:
# https://arxiv.org/pdf/1509.06344.pdf
# Simple stretch equations
# read input
img = cv2.imread("rings.png")
#img = cv2.imread("ICM.png")
#img = cv2.imread("soccerball_small.jpg")
# get dimensions and center
h, w = img.shape[:2]
xcent = w / 2
ycent = h / 2
# set up the maps as float32 from output square (x,y) to input circle (u,v)
map_u = np.zeros((h, w), np.float32)
map_v = np.zeros((h, w), np.float32)
# create u and v maps where x,y is measured from the center and scaled from -1 to 1
# note: copysign(1,x) is signum(x) and returns 1 ,0, or -1 depending upon sign of x
for y in range(h):
Y = (y - ycent)/ycent
for x in range(w):
X = (x - xcent)/xcent
X2 = X*X
Y2 = Y*Y
XY = X*Y
R = math.sqrt(X2+Y2)
if R == 0:
map_u[y, x] = xcent
map_v[y, x] = ycent
elif X2 >= Y2:
map_u[y, x] = xcent * math.copysign(1, X) * X2/R + xcent
map_v[y, x] = ycent * math.copysign(1, X) * XY/R + ycent
else:
map_u[y, x] = xcent * math.copysign(1, Y) * XY/R + xcent
map_v[y, x] = ycent * math.copysign(1, Y) * Y2/R + ycent
# do the remap
result = cv2.remap(img, map_u, map_v, cv2.INTER_LINEAR, borderMode = cv2.BORDER_REFLECT_101, borderValue=(0,0,0))
# save results
cv2.imwrite("rings_circle2square2.png", result)
#cv2.imwrite("ICM_circle2square2.png", result)
#cv2.imwrite("soccerball_small_circle2square2.png", result)
# display images
cv2.imshow('img', img)
cv2.imshow('result', result)
cv2.waitKey(0)
cv2.destroyAllWindows()
输入:
结果:
输入:
结果:
输入:
结果:
推荐阅读
- python - 在 python 中合并多个大型数据框的最佳方法是什么?
- javascript - 强制尚未安装到 DOM 渲染的 React 组件?
- css - 如何为 Tumblr 上的永久链接页面指定帖子内容的宽度?
- python - 如何使用请求获取远程地址 - python
- hibernate - 如何处理唯一字段的 SqlIntegrityConstraintViolationException?
- javascript - 简单的嵌套对象在 Chrome 控制台中产生“SyntaxError: Unexpected token”?
- java - 如何修复为 jOOQ 中的 INPUT 参数生成正确的值类型,以便使用生成的用户定义的 PL/pgSQL 函数
标签? - youtube - 我的 youtube 应用程序允许我访问一个 youtube 频道但不能访问另一个频道,有什么原因吗?
- c++ - 使用 Qt 15.3.1 进行远程调试时无法加载 qtcreatorcdbext.dll
- azure - Microsoft Azure - 制作 FTP 用户凭据时无法满足密码要求