投影变换##

在放射变换中,物体是在二维空间中变换的。如果物体在三维空间中发生了旋转,那么这种变换就成为投影变换,在投影变换中就会出现阴影或者遮挡,我们可以运用二维投影对三维投影变换进行模块化,来处理阴影或者遮挡。在OpenCV中有类似于getAffineTransform函数:getPerspectiveTransform(src,dst)函数 用来处理计算投影变换矩阵。与getAffineTransform函数不同的是传入的参数是三维空间坐标系的空间坐标,也就是4*2的二维ndarray,其中每一行代表一个坐标并且传入的数据类型必须为float32.示例:

import cv2
import numpy as np
src=np.array([[0,0],[100,0],[0,100],[100,100]],np.float32)
dst=np.array([[100,10],[100,10],[50,70],[200,150]],np.float32)
P=cv2.getPerspectiveTransform(src,dst)
print(P)

运行结果:

[[-7.77156117e-16 -1.00000000e+00  1.00000000e+02]
[-2.77555756e-15 -1.00000000e-01 1.00000000e+01]
[-2.66713734e-17 -1.00000000e-02 1.00000000e+00]]

由结果可以看出当前输出的类型是float64.对于仿射变换在OpenCV中提供了如下的函数

cv2.warpPerspective(src,M,dsize[,dst[,flags[,borderMode[,borderValue]]]])

输入的矩阵类型是3行3列的投影变换矩阵。示例:

import cv2
import numpy as np
import matplotlib def Perspect(path):
img=cv2.imread(path,cv2.IMREAD_GRAYSCALE)
if not isinstance(img, np.ndarray):
print('PASS')
pass
else:
h,w=img.shape
#设置变换坐标变化
src=np.array([[0,0],[w-1,0],[0,h-1],[w-1,h-1]],np.float32)
dst=np.array([[100,100],[w/3,100],[100,h-1],[w-1,h-1]],np.float32)
#计算投影变换矩阵
P=cv2.getPerspectiveTransform(src,dst)
#利用变化矩阵进行投影变换
r=cv2.warpPerspective(img,P,(w,h),borderValue=126)
#显示图像
cv2.imshow('A',img )
cv2.imshow('B',r)
cv2.waitKey(0)
cv2.destroyAllWindows()
print(P)
Perspect('img/aa.jpg')

极坐标变换##

极坐标变换主要处理校正图像中的圆形物体或者在圆形中物体

1.将笛卡尔坐标转换为极坐标####

\(r=\sqrt{(x-(\overline{x})^2)+(y-(\overline{y})^2)}\)

\[\theta=
\left\{
\begin{matrix}
2\pi +arctan2(y-\overline{y},x-\overline{x}), &y-\overline{y}\leq0\\
arctan2(y-\overline{y},x-\overline{x},&y-\overline{y}>0
\end{matrix}
\right\}
\]

以变换中心为圆心的同一个圆心上的点,在极坐标系\(\theta\)or中显示为一条直线。其中\(\theta\)的取值范围为[0,2\(\pi\)],函数arctan2返回的角度和笛卡尔积坐标点所在的象限有关系。举例,(9,15)以(2,10)为中心进行极坐标的变换,示例代码:

#半径转换
r=math.sqrt(math.pow(9-2,2)+math.pow(15-10,2));
#角度转换
theta=math.atan2(15-10,9-2)/math.pi*180

该示例可以这样理解,先把坐标原点移动到(2,10)处,则(9,15)平移后的坐标变为(7,5),然后再以(0,0)为中心进行转换。在OpenCV中的函数cartToPolar(x,y[,magnitude[, angle[,angleIndegress ]]])实现的就是将原点移动到变换中心后的笛卡尔积坐标向极坐标的变换,返回值magnitude,angle是与参数x,y具有相同尺寸和数据类型的ndarray。angleInDegrees的值为True时,返回值为角度,反之返回值为弧度。

例如:计算(0,0)、(1,0)、(2,0)、(0,1)、(1,1)、(2,1)、(0,2)、(1,2)、(2,2)这九个点以(1,1)为中心进行的坐标转换。首先将坐标原点移动到(1,1)处,按照平移放射矩阵计算出这九个点平移后的新坐标值,然后利用函数cartToPolar进行极坐标的转换。代码表示为:

import cv2
import numpy as np
x=np.array([[0,1,2],[0,1,2],[0,1,2]],np.float64)-1
y=np.array([[0,0,0],[1,1,1],[2,2,2]],np.float64)-1
r,theta = cv2.cartToPolar(x,y,angleInDegrees=True)
print("r: %s"%r)
print("theta: %s"%theta)

运行结果:

可以看到执行后的极坐标(\(\theta\),r)

以上九个点的图像表示就是以(1,1)为圆心的九个点,距离变换中心相等的点转换为极坐标后在极坐标系中位于同一条直线上。这样就直观的给出了极坐标变换是如何校正图像中的圆形物体或者圆环中的物体的。

2.将极坐标转换为笛卡儿坐标####

极坐标的变换是可逆的,在已知极坐标和笛卡儿坐标的条件下,计算哪个笛卡儿坐标以(\(\overline{x}\),\(\overline{y}\))为中心的极坐标变换时(\(\theta\),r),计算公式为:

\[x= \overline{x}+rcos\theta, y=\overline{y}+rsin\theta
\]

在OpenCV中的实现函数是 cv2.polarToCart(magnitude,angle[,x[, y[, angleInDegrees ]]] )来实现将极坐标转化为笛卡尔坐标。其参数与cartToPolar参数类似。代码举例 实现 根据极坐标系的(30,20),(31,21),(30,10),(30,10)四个点计算迪卡儿坐标系的哪四个点以(-6,6)为中心变换得到的。

import cv2
import numpy as np
# 将迪卡儿坐标转换为极坐标
angle = np.array([[30, 31], [30, 30]], np.float32)
r = np.array([[20, 21], [10, 10]], np.float32)
x, y = cv2.polarToCart(r, angle, angleInDegrees=True)
print("变换中心为(0,0) 得到的四个迪卡儿坐标")
print("x: %s" % x)
print("y: %s" % y) x+=-6
y+=6
print("变换中心为(-6,6) 得到的四个迪卡儿坐标")
print("x: %s" % x)
print("y: %s" % y)

运行结果:

3.利用极坐标变换实现图像修正####

我们利用极坐标和迪卡儿坐标的意义对应关系得到O的每一个像素值:

\[O(r,\theta)=f_{1}( \overline{x}+rcos\theta,\overline{y}+rsin\theta)
\]

此公式中的图像输出是以1为步长进行离散化的,但是这样的化输出的图像矩阵会出现失真的情况,丢失跟多的图像信息,。我们的解决方法是将与(\(\overline{x}\),\(\overline{y}\))的距离范围为[\(r_{min}\),\(r_{max}\)]并且角度范围在 \([\theta_{min},\theta_{max}]\)内的点进行极坐标向笛卡尔坐标的变换,并且进行离散化。\(\theta\)的变换步长\(\theta_{step}\)一般取\(\tfrac{360}{180*N}\),N\(\ge\) 2,此时输出的宽为w \(\approx\) \(\tfrac{r_{max}-r_{min}}{r_{step}}\) 图像矩阵的第i行第j列可通过以下的公式进行计算:

\[O(i,j)= F_1 (\overline{x}+(r_{min}+r_{step}i)* cos(\theta_{min}+\theta_{step}j),\overline{y}+(r_{min}+r_{step}i)*sin(\theta_{min}+\theta_{step}j))
\]

下面我们通过一个具体的实例来实现极坐标的变换:将一个圆环图像变成矩形图像

import cv2
import numpy as np
import sys #实现图像的极坐标的转换 center代表及坐标变换中心‘;r是一个二元元组,代表最大与最小的距离;theta代表角度范围
#rstep代表步长; thetastap代表角度的变化步长
def polar(image,center,r,theta=(0,360),rstep=0.5,thetastep=360.0/(180*4)):
#得到距离的最小值、最大值
minr,maxr=r
#角度的最小范围
mintheta,maxtheta=theta
#输出图像的高、宽 O:指定形状类型的数组float64
H=int((maxr-minr)/rstep)+1
W=int((maxtheta-mintheta)/thetastep)+1
O=125*np.ones((H,W),image.dtype)
#极坐标转换 利用tile函数实现W*1铺成的r个矩阵 并对生成的矩阵进行转置
r=np.linspace(minr,maxr,H)
r=np.tile(r,(W,1))
r=np.transpose(r)
theta=np.linspace(mintheta,maxtheta,W)
theta=np.tile(theta,(H,1))
x,y=cv2.polarToCart(r,theta,angleInDegrees=True)
#最近插值法
for i in range(H):
for j in range(W):
px=int(round(x[i][j])+cx)
py=int(round(y[i][j])+cy)
if((px>=0 and px<=w-1) and (py>=0 and py<=h-1)):
O[i][j]=image[py][px] return O if __name__=="__main__":
img = cv2.imread("img/yu.jpg", cv2.IMREAD_GRAYSCALE)
# 传入的图像宽:600 高:400
h, w = img.shape[:2]
print("h:%s w:%s"%(h,w))
# 极坐标的变换中心(300,200)
cx, cy = 300, 200
# 圆的半径为10 颜色:灰 最小位数3
cv2.circle(img, (int(cx), int(cy)), 10, (255, 0, 0, 0), 3)
L = polar(img, (cx, cy), (100, 350))
# 旋转
L = cv2.flip(L, 0)
# 显示与输出
cv2.imshow('img', img)
cv2.imshow('O', L)
cv2.waitKey(0)
cv2.destroyAllWindows()

OpenCV图像变换二 投影变换与极坐标变换实现圆形图像修正的更多相关文章

  1. OpenCV——PS 滤镜算法之极坐标变换到平面坐标

    // define head function #ifndef PS_ALGORITHM_H_INCLUDED #define PS_ALGORITHM_H_INCLUDED #include < ...

  2. opencv C++极坐标变换

    #include<opencv2/core/core.hpp> #include<opencv2/highgui/highgui.hpp> #include<opencv ...

  3. OPENCV图像变换-1

    图像变换是指将一幅图像变换为图像数据的另一种表现形式,例如将图像进行傅立叶变换,或者对图像进行X,Y方向的求导等,经过这些变换,可以将图像数据处理中的某些问题换一个别的角度想办法,所以图像变换是图像处 ...

  4. 【OpenCV入门教程之十四】OpenCV霍夫变换:霍夫线变换,霍夫圆变换合辑

    http://blog.csdn.net/poem_qianmo/article/details/26977557 本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog ...

  5. 学习 opencv---(13)opencv霍夫变换:霍夫线变换,霍夫圆变换

    在本篇文章中,我们将一起学习opencv中霍夫变换相关的知识点,以及了解opencv中实现霍夫变换的HoughLines,HoughLinesP函数的使用方法,实现霍夫圆变换的HoughCircles ...

  6. 【OpenCV新手教程之十四】OpenCV霍夫变换:霍夫线变换,霍夫圆变换合辑

    本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/26977557 作者:毛星云(浅墨) ...

  7. OpenCV —— 图像变换

    将一副图像转变成另一种表现形式 ,比如,傅里叶变换将图像转换成频谱分量 卷积 —— 变换的基础 cvFilter2D  源图像 src 和目标图像 dst 大小应该相同 注意:卷积核的系数应该是浮点类 ...

  8. OpenCV中的霍夫线变换和霍夫圆变换

    一.霍夫线变换 霍夫线变换是OpenCv中一种寻找直线的方法,输入图像为边缘二值图. 原理: 一条直线在图像二维空间可由两个变量表示, 例如: 1.在 笛卡尔坐标系: 可由参数: (m,b) 斜率和截 ...

  9. OpenCV计算机视觉学习(11)——图像空间几何变换(图像缩放,图像旋转,图像翻转,图像平移,仿射变换,镜像变换)

    如果需要处理的原图及代码,请移步小编的GitHub地址 传送门:请点击我 如果点击有误:https://github.com/LeBron-Jian/ComputerVisionPractice 图像 ...

随机推荐

  1. 双重 hash

    #include<stdio.h> #include<map> #include<queue> #include<algorithm> using na ...

  2. crawler 听课笔记 碎碎念 1 初步了解各种选择器极其简单的使用

    css中 身份证  id对应# 衣服      class对应 . 图片 pyquery...as pq html= request.get(url=''.....'') doc=pq(html) d ...

  3. Dijkstra求解单源最短路径

    Dijkstra(迪杰斯特拉)单源最短路径算法 Dijkstra思想 Dijkstra是一种求单源最短路径的算法. Dijkstra仅仅适用于非负权图,但是时间复杂度十分优秀. Dijkstra算法主 ...

  4. moco响应中文乱码

    moco版本为:moco-runner-standalone-0.11.1.jar 在一次使用moco框架的时候,浏览器查看响应时,发现返回来的中文是乱码. 按照网上的操作,在响应结果中加上heade ...

  5. JPA_映射关联关系

    一:单项多对一的关联关系 例如:订单和客户 1.新创建订单类 package com.atguigu.jpa.helloworld; import javax.persistence.Column; ...

  6. 内部类、final与垃圾回收,面试时你一说,面试官就知道

    内部类并不常用,而且使用起来有一定的定式,比如在下面的InnterDemoByTrhead.java里,我们通过内部类的形式创建线程. 1 public class InnerDemoByThread ...

  7. 工具 之uniq

    uniq命令的作用:显示唯一的行,对于那些连续重复的行只显示一次!接下来通过实践实例说明. [关键字] Linux Shell uniq 看test.txt文件的内容,可以看到其中的连续重复行 [ro ...

  8. zabbix3.4搭建微信报警

    身为小白的我在历经被百度查到的资料坑了无数次之后,终于找到了一个正确的文档,下面是我自己的对于安装过程的理解与阐述. 一.申请微信企业号,获取以下数据. 企业ID:(在我们企业最下方可以看到) 应用的 ...

  9. .net core 认证与授权(二)

    前言 这篇紧接着一来写的,在第一篇中介绍了认证与授权,同时提出了这套机制其实就是模拟现实中的认证与授权. 同样这篇介绍在这套机制下,用户信息管理机制?这里就会问了,上一篇中认证和授权不是都ok了吗,怎 ...

  10. LeetCode 380. Insert Delete GetRandom O(1) 常数时间插入、删除和获取随机元素(C++/Java)

    题目: Design a data structure that supports all following operations in averageO(1) time. insert(val): ...