开始打江山啦,打江山啦,朕的江山从这里开始。
import numpy as np
import cv2
import matplotlib
from matplotlib import pyplot as plt
filename = 'tilef.jpg'
img = cv2.imread(filename)
plt.imshow(img ,cmap = 'gray')
plt.show()
随朕出征,一起征服星辰大海吧!
获取图像中的坐标点并打印出来
我们可以看到,如果我们希望获取信息的点在图像中有十字标。
[(37.4032258064516, 96.33870967741936),
(263.2096774193548, 178.59677419354836),
(329.33870967741933, 52.79032258064518),
(155.9516129032258, 6.016129032258107)]
霍夫变化原理
与笛卡尔坐标相对应,我们建立霍夫坐标系,横坐标为斜率,纵坐标为截距。
记住最重要的一点,笛卡尔坐标空间的一点映射到霍夫坐标系是一条直线,笛卡尔坐标系下的一条直线映射到霍夫坐标系下就是一个点。
如果笛卡尔坐标系下确定了两个点,他们可以连接成一直线,在霍夫空间则为两条相交的直线。在霍夫空间通过一点的直线越多,证明在笛卡尔空间里,有越多的点实在一条直线上。
我们OpenCV里面用到的是
cv2.HoughLines(edges, 1, np.pi/180,200)
- 第一个参数是输入图像,且必须是二值图像,在进行霍夫变换之前需要采用阈值法的边缘检测;
- 第二和第三个参数分别是r,θ对应的精度;
- 第四个参数是阈值,判定为直线投票数的最小值;注意,投票数取决于直线上点的个数,因此这个阈值代表了检测到的直线的最短长度。
# find lines in an image by using the Hough transform
#change our image into gray one
gray = cv2.cvtColor(img1,cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray,50,200)
plt.figure("detect line")
plt.subplot(121),plt.imshow(edges,'gray')
plt.xticks([]),plt.yticks([])
# hough transform
lines = cv2.HoughLines(edges,1,np.pi/180,160)
# 返回值中的每一个元素都是一对浮点数,表示检测到的直线参数(\rho,\theta)
# 其类型为np.ndarray
lines1 = lines[:,0,:]
#提取为为二维
for rho,theta in lines1[:]:
a = np.cos(theta)
b = np.sin(theta)
x0 = a*rho
y0 = b*rho
x1 = int(x0 + 1000*(-b))
y1 = int(y0 + 1000*(a))
x2 = int(x0 - 1000*(-b))
y2 = int(y0 - 1000*(a))
cv2.line(img1,(x1,y1),(x2,y2),(255,0,0),1)
plt.subplot(122),plt.imshow(img1,)
plt.xticks([]),plt.yticks([])
plt.show()
仿射变换
仿射变换是指图像可以通过一系列的几何变化来实现平移,旋转等,保持图像的平直性和平行性。(直线仍是直线,平行线仍是平行线)
为了得到仿射变换的4points,我们需要转换一下数据类型。我们先来探索一下:
>>> import numpy as np
>>> list=[(38.81034308370755, 94.5354816523041), (263.86192701379616, 177.25992232067), (329.6304264271554, 50.34727110895335), (156.98811546708743, 5.645244163935786)]
>>> list
[(38.81034308370755, 94.5354816523041), (263.86192701379616, 177.25992232067), (329.6304264271554, 50.34727110895335)