我试图拍照(.jpg文件),并在此图片中找到两个不同颜色的圆圈的确切中心(x / y坐标)。我在python 2.7中完成了这个。我的程序运行良好,但需要很长时间,我需要大幅减少执行此操作所需的时间。我目前检查每个像素并测试其颜色,并且我知道通过预采样像素子集(例如,水平和垂直方向上的每十个像素以找到要磨练的图像区域),我可以极大地提高效率。我的问题是,是否有预先开发的函数或方法来查找比我的代码更有效的对象的x / y坐标。我已经在循环中删除了函数调用,但这只会将运行时间减少几个百分点。
这是我的代码:
from PIL import Image
import numpy as np
i = Image.open('colors4.jpg')
iar = np.asarray(i)
(numCols,numRows) = i.size
print numCols
print numRows
yellowPixelCount = 0
redPixelCount = 0
yellowWeightedCountRow = 0
yellowWeightedCountCol = 0
redWeightedCountRow = 0
redWeightedCountCol = 0
for row in range(numRows):
for col in range(numCols):
pixel = iar[row][col]
r = pixel[0]
g = pixel[1]
b = pixel[2]
brightEnough = r > 200 and g > 200
if r > 2*b and g > 2*b and brightEnough: #yellow pixel
yellowPixelCount = yellowPixelCount + 1
yellowWeightedCountRow = yellowWeightedCountRow + row
yellowWeightedCountCol = yellowWeightedCountCol + col
if r > 2*g and r > 2*b and r > 100: # red pixel
redPixelCount = redPixelCount + 1
redWeightedCountRow = redWeightedCountRow + row
redWeightedCountCol = redWeightedCountCol + col
print "Yellow circle location"
print yellowWeightedCountRow/yellowPixelCount
print yellowWeightedCountCol/yellowPixelCount
print " "
print "Red circle location"
print redWeightedCountRow/redPixelCount
print redWeightedCountCol/redPixelCount
print " "
答案 0 :(得分:1)
首先你需要做一些清算:
你认为什么足够快?样本图像在哪里,所以我们可以看到你在处理什么(分辨率,每像素位数)。什么平台(特别是 CPU ,所以我们可以估算速度)。
当您处理圆圈(每个圆圈编码不同的颜色)时,它应该足以找到边界框。因此,找到每种颜色像素的最小和最大x,y坐标。然后你的圈子是:
center.x=(xmin+xmax)/2
center.y=(ymin+ymax)/2
radius =((xmax-xmin)+(ymax-ymin))/4
如果使用您的方法编码正确,它应该只需几毫秒。对于1024x1024
分辨率左右的图像,我估计平均机器上10-100 ms
。你写的方法太慢但你没有指定时间本身(在某些情况下1us
在其他1min
中很慢就足够了,所以我们只能猜出你需要和得到的东西)。无论如何,如果你得到类似的分辨率并且时间是1-10 sec
那么你最有可能使用一些慢像素访问(很可能来自GDI),如get/setpixel
使用位图Scanline[]
或直接像素访问{{1或者为图像使用自己的记忆。
通过使用光线投射来查找圆圈的大致位置,可以加快您的方法。
投射水平线
它们的距离应小于您搜索的最小圆的半径。投射尽可能多的光线直到你用至少2条光线击中每个圆圈
投两条垂直线
你可以使用#1中找到的交叉点,所以不需要投射很多光线......使用交点较近但不太近的H光。
计算您的圈子属性
所以从4个交点计算中心和半径,因为它是轴对齐矩形+/-像素误差,它应该很容易找到任何对角线的中点,半径也明显为对角线尺寸的一半。
由于您没有分享任何图片,我们只能猜测您所拥有的内容,如果您没有圈子或需要不同方法的想法,请参阅:
答案 1 :(得分:0)
如果您确定圆圈的颜色,更容易的方法是使用蒙版过滤颜色,然后按照Mathew Pope的建议应用Hough圆圈。
这是一个让您快速入门的片段。
import cv2 as cv2
import numpy as np
fn = '200px-Traffic_lights_dark_red-yellow.svg.png'
# OpenCV reads image with BGR format
img = cv2.imread(fn)
# Convert to HSV format
img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# lower mask (0-10)
lower_red = np.array([0, 50, 50])
upper_red = np.array([10, 255, 255])
mask = cv2.inRange(img_hsv, lower_red, upper_red)
# Bitwise-AND mask and original image
masked_red = cv2.bitwise_and(img, img, mask=mask)
# Check for circles using HoughCircles on opencv
circles = cv2.HoughCircles(mask, cv2.cv.CV_HOUGH_GRADIENT, 1, 20, param1=30, param2=15, minRadius=0, maxRadius=0)
print 'Radius ' + 'x = ' + str(circles[0][0][0]) + ' y = ' + str(circles[0][0][1])
将其应用于图像的一个示例如下所示。首先是原始图像,然后是获得的红色遮罩,最后一个是使用OpenCV的Hough圆函数找到圆圈。
使用上述方法找到的半径为Radius x = 97.5 y = 99.5
希望这有帮助! :)