【问题标题】:Apply a threshold to an image (quickly)对图像应用阈值(快速)
【发布时间】:2017-07-25 11:23:59
【问题描述】:

我正在尝试构建一个支持阈值的像素计数程序。我希望用户能够快速生成输入图像上区域的预览,程序将在量化过程中将其视为“正”。

输入:

输入图像可以是 24 位 RGB TIFF 文件(叠加 3 个通道)或 16 位灰度 TIFF(每个通道一个图像,位深更大)。用户将选择他们正在加载的图像类型(“mode”变量)、他们感兴趣的通道(“desiredcolour”变量(RGB 为 0-2))以及他们想要使用的阈值( “self.threshold”变量)。输入图像分辨率约为 1400x1000。

输出:

点击“预览”按钮时,用户选择一个文件,然后会弹出一个窗口,显示该图像的预览,其中正像素以浅蓝色覆盖。我无法在程序窗口中显示 16 位灰度 tiff,因此我在生成预览时将它们转换为 RGB。将颜色应用于检测到的像素的能力在那里很有用。我还让它将预览调整为更方便的大小。

虽然下面的脚本有效,但理想情况下,我希望在用户更改阈值变量时更新预览图像。当前脚本需要几秒钟才能生成图像,因此并不理想。

目前我的主要功能如下:

import tkinter as tk
import tkinter.filedialog as tkfiledialog
from PIL import Image, ImageTk

打开预览窗口

def openpreview(self):
    global desiredcolour
    self.previewfile = Image.open(tkfiledialog.askopenfilename())
    self.logevent("Opening preview")
    self.genpreview(self.previewfile, desiredcolour)

阈值预览生成器

def genpreview(self, tgt, value):
    global mode
    self.pixellist = list(tgt.getdata())
    self.newlist=[]
    if mode.get() == "RGB" and tgt.mode[0] == "I":
        self.logevent("Error: This is not an RGB file")
        return
    elif mode.get() == "RAW" and tgt.mode[0] != "I":
        self.logevent("Error: This doesn't look like a RAW file")
        return
    for point in self.pixellist:
        if mode.get() == "RGB":
            if point[value] >= self.threshold.get():
                point = (0, 191, 255)
            self.newlist.append(point)
        if mode.get() == "RAW":
            if point >= self.threshold.get():
                point = (0, 191, 255)
            else:
                point = point//255
                point = (point, point, point)
            self.newlist.append(point)
    self.preview = Image.new("RGB", tgt.size)
    self.preview.putdata(self.newlist)
    self.preview = self.preview.resize((tgt.size[0]//2, tgt.size[1]//2))
    self.preview = ImageTk.PhotoImage(self.preview)
    self.preview_window(self.preview)

在新窗口中显示预览

def preview_window(self, outgoingimage):
    self.previewwindow = tk.Toplevel()
    self.previewwindow.wm_attributes('-toolwindow',1)
    self.previewpane = tk.Label(self.previewwindow, image=outgoingimage)
    self.previewpane.image=outgoingimage
    self.previewpane.grid(row=1, column=1)

我想知道我是否以错误的方式处理此问题,是否有更有效的方法来完成这一切?或者可能是某个地方有错误。

【问题讨论】:

    标签: python image image-processing python-imaging-library


    【解决方案1】:

    在尝试了几种不同的方法后,我最终想到的最快的方法是使用 Numpy 和 opencv 包。使用数组而不是循环遍历像素效率更高,此版本每张图像耗时约 0.05 秒,而不是上述脚本的约 0.9 秒。

    阈值预览生成器

    def genpreview(self, tgt, value):
        activemode = mode.get()
        thold = threshold.get()
        imfile = cv2.imread(tgt, -1)
        if activemode == "RGB" and imfile.dtype != "uint8":
            self.logevent("Error: This is not an RGB file")
            return
        elif activemode == "RAW" and imfile.dtype != "uint16":
            self.logevent("Error: This doesn't look like a RAW file")
            return
        if activemode == "RGB":
            mask = (imfile[:,:,value] > thold)
            imfile[mask] = (0, 191, 255)
            self.preview2 = Image.fromarray(imfile, 'RGB')
            self.preview = self.preview2.resize((self.preview2.size[0] // 2, self.preview2.size[1] // 2))
        elif activemode == "RAW":
            im = cv2.imread(tgt)
            mask = (im[:,:,1] > thold//256)
            im[mask] = (0, 191, 255)
            self.preview2 = Image.fromarray(im, 'RGB')
            self.preview = self.preview2.resize((self.preview2.size[0] // 2, self.preview2.size[1] // 2))
        self.preview = ImageTk.PhotoImage(self.preview)
    

    对于输入,“tgt”只是目标文件路径的字符串,“value”是正在分析的通道的索引。

    【讨论】:

      猜你喜欢
      • 2013-03-11
      • 2014-12-21
      • 2013-01-30
      • 1970-01-01
      • 1970-01-01
      • 2015-10-19
      • 1970-01-01
      • 2021-02-10
      • 2012-11-03
      相关资源
      最近更新 更多