OpenCV Python 逐像素循环很慢 [英] OpenCV Python pixel-by-pixel loop is slow
问题描述
我正在尝试将每个像素的色调值与给定的阈值进行比较.如果像素的色调在给定的阈值之间,它将为该特定像素绘制一个小圆圈.
I'm trying to compare every pixel's hue value with a threshold given. If the pixel's hue is between the threshold value given, it will draw a small circle to that particular pixel.
所以,我所做的是迭代照片中的每个像素并比较每个像素以查看像素的色调是否在阈值之间.但是,当我这样做时,遍历像素的速度非常慢.有没有办法加快迭代过程?
So, what I did is to iterate over every pixel from the photo and compare every pixel to see whether the pixel's hue is between the threshold or not. But, when I was doing this, the speed of iterating over the pixels are very slow. Is there any way to speed up the iterating process?
这是我所做的:
img = cv2.imread("green bottle.jpg")
imgHSV = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
h, w, d = imgHSV.shape
for i in range(h):
for j in range(w):
k = imgHSV[i, j]
if 26 <= k[0] <= 35: # the hue value threshold between 26 to 57
cv2.circle(img, (j, i), 1, (255, 0, 0)) # draw a small circle for every matching result
elif 36 <= k[0] <=77:
cv2.circle(img, (j, 1), 1, (0, 255, 0)) # draw a small circle for every matching result
cv2.imshow("Image", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
提前致谢!
推荐答案
我试了一下,想出了一些与 @rayryeng 非常相似的东西,但对我的形象来说很慢:
I had a try and came up with something pretty much identical to @rayryeng like this but it was very slow for my image:
# Load image
im = cv2.imread('smooth.png')
# Convert to HSV and extract H
H = cv2.cvtColor(im, cv2.COLOR_BGR2HSV)[..., 0]
# Mask Hues in range [26..35]
rangeA = np.logical_and(H>=26, H<=35)
# Get coordinates of selected pixels and plot circle at each
for y,x in np.argwhere(rangeA):
cv2.circle(im, (x,y), 1, (255,255,255))
当我计时的时候,我意识到所有的时间都被cv2.circle()
占用了.所以我看着半径为 1 的圆,它看起来像这样:
When I timed it, I realised all the time was taken by cv2.circle()
. So I looked at the circle of radius 1 and it looks like this:
0 1 0
1 0 1
0 1 0
与 3x3 形态交叉极其相似:
which is extremely similar to a 3x3 morphological cross:
0 1 0
1 1 1
0 1 0
所以,我用形态学而不是 cv2.circle()
来绘制圆圈,我得到了这个:
So, I drew the circles with morphology rather than cv2.circle()
, and I got this:
#!/usr/bin/env python3
import cv2
import numpy as np
# Load image
im = cv2.imread('smooth.png')
# Convert to HSV and extract H
H = cv2.cvtColor(im, cv2.COLOR_BGR2HSV)[..., 0]
# Mask Hues in range [26..35]
rangeA = np.logical_and(H>=26, H<=35)
# Note that a circle radius 1 is a 3x3 cross, so rather than
# draw circles we can convolve with a ring
ring = cv2.getStructuringElement(cv2.MORPH_CROSS, (3,3))
ring[1,1]=0
res = cv2.morphologyEx((rangeA*255).astype(np.uint8), cv2.MORPH_DILATE, ring)
# Save result
cv2.imwrite('result.png', res)
所以,如果我从这个开始:
So, if I start with this:
我在很短的时间内得到了这个:
I got this in a fraction of the time:
使用 for
循环后,我的图像上的时间为 5 毫秒,如下所示:
Timings on my image were 5ms as follows with for
loop:
In [133]: %%timeit
...: for y,x in np.argwhere(rangeA):
...: cv2.circle(im, (x,y), 1, (255,255,255))
...:
4.98 ms ± 42.6 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
和 159 微秒扩张:
and 159 microseconds with dilation:
%timeit cv2.morphologyEx((rangeA*255).astype(np.uint8), cv2.MORPH_DILATE, ring)
159 µs ± 4.13 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
这篇关于OpenCV Python 逐像素循环很慢的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!