在学习一段代码的时候 有段代码阅读的不是很懂 该段代码的目的是通过旋转虚拟指针找到和原指针重合最高的地方 并求出角度
t1 = img.copy(); t1[temp[:, :, 2] == 255] = 255; c = img[temp[:, :, 2] == 255]; points = c[c == 0]; freq_list.append((len(points), i))
这五行代码就十分疑惑不知所云 不知道各位朋友能不能详细解惑一番
def get_pointer_rad(img):
shape = img.shape
c_y, c_x, depth = int(shape[0] / 2), int(shape[1] / 2), shape[2]
x1=c_x+c_x*0.8
src = img.copy()
freq_list = []
for i in range(361):
x = (x1 - c_x) * cos(i * pi / 180) + c_x
y = (x1 - c_x) * sin(i * pi / 180) + c_y
temp = src.copy()
cv2.line(temp, (c_x, c_y), (int(x), int(y)), (0, 0, 255), thickness=3)
t1 = img.copy()
t1[temp[:, :, 2] == 255] = 255
c = img[temp[:, :, 2] == 255]
points = c[c == 0]
freq_list.append((len(points), i))
cv2.imshow('d', temp)
cv2.imshow('d1', t1)
cv2.waitKey(1)
print('当前角度:',max(freq_list, key=lambda x: x[0]),'度')
cv2.destroyAllWindows()
return max(freq_list, key=lambda x: x[0])
你这个格式确定没问题吗?对齐了很好理解了。前面几行看图应该就能理解是干什么的,从11开始,就是在temp中画一条(c_x,c_y)到点(x,y)的红色的直线,13行是判断temp中,如果某个点的红色通道灰度值为255,则将t1中同样位置的该点的颜色置为255(白色),14行c是将temp中红色通道为白色(255)的位置置为True,其他为false,15行是将C中等于0的点位置坐标传给points(确定这里没错吗?应该是c==True才能符合预期效果吧),
然后freq_list 保存points的长度和此时的角度i。最后几行的显示图像,20和22的max()是找到freq_list[0]中最大的点。
综合起来说,就是用一个旋转的直线,来判断图中和直线重合的点最多的直线的旋转角度是多少,及最后的重合点的个数(15行要修改才行),像下面的那个图,最后的结果就是重合点最多的是3261个,旋转角是319度
import cv2
from math import cos,sin,pi
import numpy as np
def get_pointer_rad(img):
shape = img.shape
c_y, c_x, depth = int(shape[0] / 2), int(shape[1] / 2), shape[2]
x1=c_x+c_x*0.8
src = img.copy()
freq_list = []
for i in range(361):
x = (x1 - c_x) * cos(i * pi / 180) + c_x
y = (x1 - c_x) * sin(i * pi / 180) + c_y
temp = src.copy()
cv2.line(temp, (c_x, c_y), (int(x), int(y)), (0, 0, 255), thickness=3)
t1 = img.copy()
t1[temp[:, :, 2] == 255] = [0,0,255]
c = img[temp[:, :, 2] == 255]
points = c[c == True]
freq_list.append((len(points), i))
cv2.imshow('d', temp)
cv2.imshow('d1', t1)
cv2.waitKey(1)
print('当前角度:',max(freq_list, key=lambda x: x[0]),'度')
cv2.destroyAllWindows()
return max(freq_list, key=lambda x: x[0])
img=np.ones((500,500),np.uint8)
img=cv2.cvtColor(img,cv2.COLOR_GRAY2BGR)
cv2.line(img,(250,250),(20,20),(0,0,255),3,8)
get_pointer_rad(img)
#output
当前角度: (3261, 319) 度
img是一个RGB图像的三维数组,其上有一个黑色的指针,指针旋转的圆心在图像中心。要想知道这个指针的角度,就在img的一个副本temp上以图像中心为圆心,从0°~360°循环,做以下工作:画蓝色线条,找出temp上蓝点的位置(temp[:, :, 2] == 255),得到img上对应位置的像素中蓝色通道的数值组成的数组c,数组c中等于0的元素组成points,将points长度和当前的角度存到列表(freq_list)中。很显然,如果在某个角度画出的蓝色线条正好和指针重合,那么points中0的个数一定最多,因为指针是黑色的,指针之外的像素都不是黑色的。
如果img是BGR模式,那么上面描述中的蓝色都变成红色。
不过,这个代码写得不好:
为了帮助题主理解numpy,我写了几行简单的代码:
>>> import numpy as np
>>> img = np.random.randint(0,256,(3,4,3)) # 生成一个3行4列的RGB图像数组
>>> temp = img.copy() # 复制
>>> img
array([[[ 45, 95, 97],
[198, 105, 214],
[243, 218, 121],
[156, 227, 212]],
[[203, 161, 33],
[ 88, 214, 21],
[102, 144, 13],
[178, 45, 17]],
[[214, 247, 234],
[ 7, 33, 184],
[251, 127, 151],
[101, 162, 138]]])
>>> c = img[temp[:,:,2] > 128] # 对应temp中蓝色通道数值大于128的位置,img的蓝色通道数值组成的数组
>>> c
array([[198, 105, 214],
[156, 227, 212],
[214, 247, 234],
[ 7, 33, 184],
[251, 127, 151],
[101, 162, 138]])
>>> points = c[c < 50] # 小于50的元素
>>> points
array([ 7, 33])