对图像应用阈值(快速)

时间:2017-03-05 17:01:06

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

我正在尝试构建一个支持阈值处理的像素计数程序。我希望用户能够快速生成输入图像上的区域预览,程序在定量时会认为是“正”。

输入

输入图像将是24位RGB TIFF文件(3个通道重叠)或16位灰度TIFF(每个通道一个图像具有更大的位深度)。用户将选择他们正在加载的图像类型(“模式”变量),他们感兴趣的通道(“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)

Diplay预览在新窗口中

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)

我想知道我是否以错误的方式接近这个并且有更有效的方法来做这一切?或许某处可能出现了错误。

1 个答案:

答案 0 :(得分:0)

在尝试了几种不同的方法后,我最终提出的最快的方法是使用Numpy和opencv软件包。使用数组而不是循环遍历像素效率更高,这个版本每张图片大约需要0.05s而不是上面脚本大约0.9s。

阈值预览生成器

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"只是一个目标文件的路径和"值"是被分析渠道的索引。