OpenCV Python逐像素循环速度较慢

OpenCV Python逐像素循环速度较慢,python,numpy,opencv,Python,Numpy,Opencv,我试图将每个像素的色调值与给定的阈值进行比较。如果像素的色调介于给定的阈值之间,它将为该特定像素绘制一个小圆圈 所以,我所做的是迭代照片中的每个像素,比较每个像素,看看像素的色调是否在阈值之间。但是,当我这样做的时候,迭代像素的速度非常慢。有没有办法加快迭代过程 以下是我所做的: img = cv2.imread("green bottle.jpg") imgHSV = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) h, w, d = imgHSV

我试图将每个像素的色调值与给定的阈值进行比较。如果像素的色调介于给定的阈值之间,它将为该特定像素绘制一个小圆圈

所以,我所做的是迭代照片中的每个像素,比较每个像素,看看像素的色调是否在阈值之间。但是,当我这样做的时候,迭代像素的速度非常慢。有没有办法加快迭代过程

以下是我所做的:

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()
img=cv2.imread(“绿瓶.jpg”)
imgHSV=cv2.CVT颜色(img,cv2.COLOR_BGR2HSV)
h、 w,d=进气歧管空腔形状
对于范围(h)内的i:
对于范围(w)内的j:
k=进气歧管空速[i,j]

如果26我建议将此矢量化,首先找到色调介于26和35之间以及色调介于36和77之间的圆圈,然后在图像上绘制它们
cv2.circle
不幸的是,它没有矢量化,因为它被设计为只获取一对坐标,但是搜索感兴趣的像素可以更快

尝试:

将numpy导入为np
进口cv2
img=cv2.imread(“绿瓶.jpg”)
imgHSV=cv2.CVT颜色(img,cv2.COLOR_BGR2HSV)
色调=imgHSV[…,0]

(rows1,cols1)=np.where(np.logical_和(色调>=26,色调=36,色调我建议将其矢量化,首先找到色调介于26和35之间以及色调介于36和77之间的圆,然后在图像上绘制它们。
cv2.circle
不幸的是,它没有矢量化,因为它被设计为只获取一对坐标,而搜索像素兴趣可以做得更快

尝试:

将numpy导入为np
进口cv2
img=cv2.imread(“绿瓶.jpg”)
imgHSV=cv2.CVT颜色(img,cv2.COLOR_BGR2HSV)
色调=imgHSV[…,0]

(rows1,cols1)=np.where(np.logical_)和(hue>=26,hue=36,hue我试了一下,找到了一个与@rayryeng非常相似的东西,就像这样,但对我的图像来说速度非常慢:

# 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))
与3x3形态杂交非常相似:

0 1 0
1 1 1
0 1 0

因此,我用形态学而不是
cv2.circle()
绘制了这些圆,得到了以下结果:

#!/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)
和159微秒的膨胀:

%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)

我试了一下,想出了一个与@rayryeng非常相似的东西,就像这样,但对于我的图像来说,速度非常慢:

# 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))
与3x3形态杂交非常相似:

0 1 0
1 1 1
0 1 0

因此,我用形态学而不是
cv2.circle()
绘制了这些圆,得到了以下结果:

#!/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)
和159微秒的膨胀:

%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)

这里的瓶颈一定是绘图函数,它似乎没有矢量化。为什么不直接使用cv2.inRange()设置图像的阈值。如果要绘制圆,请从阈值图像中找到每个白色像素的坐标(使用np.argwhere)然后用这些作为圆心来画圆。@fmw42嗨!谢谢你的回答,很抱歉,我想我必须重新表述我的问题,我以前曾想过使用cv2.inRange(),但实际上我有几个if语句,如上图所示(编辑版)。因此,对于每个不同的阈值,将有不同的颜色圈。我认为使用fmw42的建议。只需对每个阈值执行多次此操作。然后分别绘制它们。我认为这是最快的。您可以使用inRange()两次(每个条件一次)然后组合遮罩。然后像我上面提到的那样继续。这里的瓶颈必须是你的绘图函数,它似乎没有矢量化。为什么不直接使用cv2.inRange()来设置图像的阈值。如果你想画圆,那么从阈值图像中找到每个白像素的坐标(使用np.argwhere)然后用这些作为圆心来画圆。@fmw42嗨!谢谢你的回答,很抱歉,我想我必须重新表述我的问题,我以前曾想过使用cv2.inRange(),但实际上我有几个if语句,如上图所示(编辑版)。因此,对于每个不同的阈值,都会有不同的颜色圈。我想使用fmw42的建议。只需对每个阈值执行多次此操作。然后分别绘制它们。我认为这是最快的。您可以使用inRange()两次(每个条件一次),然后组合遮罩。然后按照我上面提到的方法进行操作。