c语言矩形极坐标变成圆,使用Python和极坐标变换将椭圆环展开为矩形

最近的工作中遇到了一个问题,查了挺久发现没有相应的实现方式,于是自己摸索着写了一个椭圆环展开成为矩形长条的python算法,记录一下备忘。

8bb6af03727d968ed40f0cd86bc72524.png

0x00代码

废话不多说先上代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18import cv2

import numpy as np

import math

def get_word_by_circle(img,circle_center,radius,radius_width):

black_img = np.zeros((radius_width,int(radius[1]*(radius[0]+radius[1])/radius[0])+500,3),dtype='uint8')

for row in range(0,black_img.shape[0]):

for col in range(0,black_img.shape[1]):

theta = 0-(math.pi*2/black_img.shape[1]*(col+1)+1.57)

rho = int((radius[0]*radius[1])/(((radius[1]**2)*(math.cos(theta)**2)+(radius[0]**2)*(math.sin(theta)**2))**0.5))-row-1

p_x = int(circle_center[0] + rho*math.cos(theta))

p_y = int(circle_center[1] - rho*math.sin(theta))

black_img[row,col,:] = img[p_y,p_x,:]

return black_img

参数解释:

img是用cv2.imread读入的带有椭圆的图片;circle_center指的是椭圆圆心的坐标数据,是一个列表,相对于左上角[x,y];radius是一个列表,[长轴半径,短轴半径];radius_width指的是椭圆环的宽度

最终生成的矩形长条,以椭圆环的外周长为长(实际上由于展开的是椭圆的印章,便于查看,增加了长),以椭圆环的宽度为高。函数中,从椭圆环的最外圈开始遍历,最外圈即对应着矩形中的第一行,宽度为多少,则矩形中就有多少行。以圆心为中心构成极坐标系,则圆环上任意一点可以用rho和theta来表示,再根据公式计算出该点在图上的真实坐标,把像素值赋给矩形框中对应的位置,极坐标转换公式如下所示:

3e6b3f8ea2f0ec9d3ea60fb6c526a0e2.png

0x01效果

效果图如下:

c7158390d1819cd690aad8c7705f219b.png

5d11c7bdd848e5531f6a7d3f04073386.png

由于椭圆的定位准确度不如圆,因此展开还有一些文字扭曲问题,效果还是没有很理想,后续还会继续优化。

0x02补充

由于某些椭圆是倾斜的,因此我们需要引入一个新的参数去定义椭圆的倾斜角度inclination,单位是rad,具体实现方案参考:https://jingyan.baidu.com/article/2c8c281dfbf3dd0009252a7b.html

代码如下,增加了坐标变换:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21import cv2

import numpy as np

import math

def get_word_by_circle(img,circle_center,radius,radius_width,inclination):

black_img = np.zeros((radius_width,int(radius[1]*(radius[0]+radius[1])/radius[0])+500,3),dtype='uint8')

for row in range(0,black_img.shape[0]):

for col in range(0,black_img.shape[1]):

theta = 0-(math.pi*2/black_img.shape[1]*(col+1)+1.57-inclination)

rho = int((radius[0]*radius[1])/(((radius[1]**2)*(math.cos(theta)**2)+(radius[0]**2)*(math.sin(theta)**2))**0.5))-row-1

p_x = circle_center[0] + rho*math.cos(theta)

p_y = circle_center[1] - rho*math.sin(theta)

#坐标变换

px = int((p_x-circle_center[0])*math.cos(inclination)-(p_y-circle_center[1])*math.sin(inclination)+circle_center[0])

py = int((p_x-circle_center[0])*math.sin(inclination)+(p_y-circle_center[1])*math.cos(inclination)+circle_center[1])

black_img[row,col,:] = img[p_y,p_x,:]

return black_img

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值