Skip to main content
 首页 » 编程设计

python之我想使用 python 对图像中的像素应用阈值。我哪里弄错了

2025年05月04日20三少

我想生成作为阈值的输出。我的错误:

img_thres = n_pix[y, x]
TypeError: 'int' object is not subscriptable

import cv2 
import numpy as np 
import matplotlib as plt 
 
img = cv2.imread("cicek.png",0) 
img_rgb = cv2.imread("cicek.png") 
 
h = img.shape[0] 
w = img.shape[1] 
 
img_thres= [] 
n_pix = 0 
# loop over the image, pixel by pixel 
for y in range(0, h): 
    for x in range(0, w): 
        # threshold the pixel 
        pixel = img[y, x] 
        if pixel < 0.5: 
            n_pix = 0 
        img_thres = n_pix[y, x] 
 
cv2.imshow("cicek", img_thres) 

请您参考如下方法:

由于您已经在使用 OpenCV,您也可以使用其优化的 SIMD 代码来进行阈值处理。它不仅更短、更易于维护,而且速度更快。它看起来像这样:

_, thres = cv2.threshold(img,127,255,cv2.THRESH_TOZERO) 

是的,就是这样!这将替换您的所有代码。


基准测试和演示

大量借鉴其他答案,我将其放在一起:

  • 使用双 for 循环的方法,
  • 一个 Numpy 方法,以及
  • 我建议的 OpenCV 方法

并在 IPython 中运行了一些计时测试。所以,我将这段代码保存为 thresh.py

#!/usr/bin/env python3 
 
import cv2 
import numpy as np 
 
def method1(img): 
    """Double loop over pixels""" 
    h = img.shape[0] 
    w = img.shape[1] 
 
    img_thres= np.zeros((h,w)) 
    # loop over the image, pixel by pixel 
    for y in range(0, h): 
        for x in range(0, w): 
            # threshold the pixel 
            pixel = img[y, x] 
            img_thres[y, x] = 0 if pixel < 128 else pixel 
    return img_thres 
 
def method2(img): 
    """Numpy indexing""" 
    img_thres = img 
    img_thres[ img < 128 ] = 0 
    return img_thres 
 
def method3(img): 
    """OpenCV thresholding""" 
    _, thres = cv2.threshold(img,127,255,cv2.THRESH_TOZERO) 
    return thres 
 
img = cv2.imread("gradient.png",cv2.IMREAD_GRAYSCALE) 

然后,我启动了 IPython 并做了:

%load thresh.py 

然后,我对三种方法进行了计时:

%timeit method1(img) 
81 ms ± 545 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) 
 
%timeit method2(img) 
24.5 µs ± 818 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each) 
 
%timeit method3(img) 
3.03 µs ± 79.5 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each) 

请注意,第一个结果以毫秒为单位,而其他两个以微秒为单位。 Numpy 版本比 for 循环快 3,300 倍,OpenCV 版本快 27,000 倍!!!

您可以通过像这样计算图像中的差异来检查它们产生相同的结果:

np.sum(method1(img)-method3(img)) 
0.0  

开始图片:

结果图片: