我想使用python将阈值应用于图像中的像素.我在哪里弄错了? [英] I want to apply a threshold to pixels in image using python. Where did I make a mistake?

查看:111
本文介绍了我想使用python将阈值应用于图像中的像素.我在哪里弄错了?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to generate the output that is a threshold. And my error:

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

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代码进行阈值设置.它不仅更短,更容易维护,而且速度更快.看起来像这样:

As you are already using OpenCV, you may as well use its optimised SIMD code to do your thresholding. Not only is it shorter and easier to maintain, it is also miles faster. It looks like this:

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

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

Yes, that's it! That replaces all your code.

基准测试和演示

我大量借鉴其他答案,

  • 使用两个for循环的方法,
  • 一种Numpy方法,
  • 我建议的OpenCV方法
  • a method using double for loops,
  • a Numpy method, and
  • the OpenCV method I am suggesting

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

and ran some timing tests inside IPython. So, I saved this code as 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 并做到了:

Then, I started IPython and did:

%load thresh.py

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

Then, I timed the three methods:

%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倍快!!

Note that the first result is in milliseconds whereas the other two are in microseconds. The Numpy version is 3,300 times faster than the for loops, and that the OpenCV version is 27,000 times faster!!!

您可以像这样添加图像中的差异来检查它们是否产生相同的结果:

You can check they produce the same result by totting up the differences in the images like this:

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

起始图片:

结果图片:

这篇关于我想使用python将阈值应用于图像中的像素.我在哪里弄错了?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆