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

hol*_*boy 1 python image image-processing threshold image-thresholding

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

img_thres = n_pix[y, x]
TypeError: 'int' 对象不可下标

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)
Run Code Online (Sandbox Code Playgroud)

Mar*_*ell 5

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

\n\n
_, thres = cv2.threshold(img,127,255,cv2.THRESH_TOZERO)\n
Run Code Online (Sandbox Code Playgroud)\n\n

对,就是那样!这会替换您的所有代码。

\n\n
\n\n

基准测试和演示

\n\n

我大量借鉴了其他答案,总结如下:

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

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

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

然后,我启动了IPython并执行了以下操作:

\n\n
%load thresh.py\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n
%timeit method1(img)\n81 ms \xc2\xb1 545 \xc2\xb5s per loop (mean \xc2\xb1 std. dev. of 7 runs, 10 loops each)\n\n%timeit method2(img)\n24.5 \xc2\xb5s \xc2\xb1 818 ns per loop (mean \xc2\xb1 std. dev. of 7 runs, 10000 loops each)\n\n%timeit method3(img)\n3.03 \xc2\xb5s \xc2\xb1 79.5 ns per loop (mean \xc2\xb1 std. dev. of 7 runs, 100000 loops each)\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n

您可以通过计算图像中的差异来检查它们是否产生相同的结果,如下所示:

\n\n
np.sum(method1(img)-method3(img))\n0.0 \n
Run Code Online (Sandbox Code Playgroud)\n\n

起始图像:

\n\n

在此输入图像描述

\n\n

结果图像:

\n\n

在此输入图像描述

\n