for x in range(self.image.shape[0]):
# 图片的高
for y in range(self.image.shape[1]):
# 图片的宽
point = np.array([y,x], dtype="int")
point = tuple(np.int0(point))
if cv2.pointPolygonTest(self.cnt_max2, point, False) <= 0:
self.image[x,y]=[0,0,0]
遍历图像所有的点,把最大轮廓外面的点(背景)置黑,以达到扣出前景的目的,代码有没有什么毛病,为什么特别慢,要十几二十秒才能出来,还只有640*480,要是几百万像素的,岂不是要运行两三分钟,有木有更快的算法呢
利用np.where改进重心法检测
xy=np.where(blank_bg < 10)
listx=list(xy)[0] #行
listy=list(xy)[1] #列
point_x = np.sum(listy)/len(listy)
point_y = np.sum(listx)/len(listx)
使用np的内置函数可以大幅提高程序的运行效率。这里使用np.where来替换掉两个for循环。
np.where返回的是一个元组,n维数组的输入会返回n维元组。对图像来说,输入为二维数组(像素坐标为二维),因此返回值为2维元组,如下所示:
(array([509, 509, 509, ..., 766, 766, 766], dtype=int64), array([337, 338, 339, ..., 380, 381, 382], dtype=int64))
这个2维元组的第一个数表示满足条件的行坐标,第二个数表示满足条件的列坐标。这样就通过np.where替代了两层for循环。之后便可以根据返回的结果对像素进行操作。实测下来,该部分运行时间是0.003秒,运行效率提高了421倍。
本身你这个算法就不是很好,网上查找相关的库吧
这个程序写的,唉。两重 for 循环,加上条件分支调用 cv2,不慢才怪呢。
建议你先用 reshape, 再用 numpy 条件筛选, 就把两重 for 循环都取消了。
你都有轮廓了为什么还要去遍历?直接用mask覆盖一下就行,或者用位运算与一下
mask = np.zeros((img.shape[0],img.shape[1]),dtype=np.uint8)
mask = cv2.drawContours(mask, self.[cnt_max2], -1, (255), -1, 8) # 绘制轮廓区域制作mask
#一种用copyTo获得
out=cv2.copyTo(img,mask=mask)
#一种直接用位运算获取
out=image&mask
用OpenCV库就很简单
for x in range(self.image.shape[0]):
# 图片的高
for y in range(self.image.shape[1]):
# 图片的宽
point = np.array([y,x], dtype="int")
point = tuple(np.int0(point))
if cv2.pointPolygonTest(self.cnt_max2, point, False) <= 0:
self.image[x,y]=[0,0,0]
双重 for 循环加上条件分支调用 cv2,会很慢