【问题标题】:How to do interactive image binarization using trackbars?如何使用轨迹栏进行交互式图像二值化?
【发布时间】:2021-03-05 06:56:05
【问题描述】:

我有一个代码,它使用 Otsu 阈值为我提供二进制图像。我正在为 U-Net 制作数据集,并且我想尝试不同的算法(全局和本地),以便保存“最佳”图像。下面是我的图像二值化代码。

import cv2
import numpy as np
import skimage.filters as filters

img = cv2.imread('math.png') # read the image
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) # convert to gray
smooth = cv2.GaussianBlur(gray, (95,95), 0) # blur
division = cv2.divide(gray, smooth, scale=255) # divide gray by morphology image

# Add Morphology here. Dilation, Erosion, Opening, Closing or so.

sharp = filters.unsharp_mask(division, radius=1.5, amount=1.5, multichannel=False, preserve_range=False) # sharpen using unsharp masking
sharp = (255*sharp).clip(0,255).astype(np.uint8)
thresh = cv2.threshold(sharp, 0, 255, cv2.THRESH_OTSU )[1]  # threshold

我在更广泛的领域得到了相当不错的结果,但我想使用cv2.namedWindowcv2.createTrackbarcv2.getTrackbarPos,以便我可以设置radiusamountkernel 的值,膨胀,腐蚀等,通过使用以下函数。

cv2.namedWindow('Tracking Window')
cv2.createTrackbar('param1','Tracking Window',0,255,dummy) # dummy is just a dummy function which returns None
param1 = cv2.getTrackbarPos('param1','Tracking Window')

我怎样才能得到所有这些。还有,按s如何保存图片,按n打开下一张图片?

Original Question was posted by me 6 months ago

【问题讨论】:

    标签: python image opencv image-processing computer-vision


    【解决方案1】:

    我的解决方案的代码比预期的要长,但它提供了一些花哨的操作可能性。首先,让我们看看实际的窗口:

    有滑块

    • 形态学操作(扩张、侵蚀、关闭、打开),
    • 结构元素(矩形、椭圆、十字)和
    • 内核大小(这里:限制在1 ... 21范围内)。

    窗口名称反映了前两个滑块的当前设置:

    当按下 s 时,图像会结合当前设置保存:

    Saved image as Erosion_Ellipsoid_SLEM_11.png.
    

    按下 n 时,将选择列表中的下一个图像。

    在任何时候,当按下 q 时,应用程序就会退出。它会在处理完列表中的所有图像后自动结束。

    在交互部分之前和之后,您可以添加任何您想要的操作,参见。代码。

    而且,这里是完整的代码:

    import cv2
    
    # Collect morphological operations
    morphs = [cv2.MORPH_DILATE, cv2.MORPH_ERODE, cv2.MORPH_CLOSE, cv2.MORPH_OPEN]
    
    # Collect some texts for later
    morph_texts = {
        cv2.MORPH_DILATE: 'Dilation',
        cv2.MORPH_ERODE: 'Erosion',
        cv2.MORPH_CLOSE: 'Closing',
        cv2.MORPH_OPEN: 'Opening'
    }
    
    # Collect structuring elements
    slems = [cv2.MORPH_RECT, cv2.MORPH_ELLIPSE, cv2.MORPH_CROSS]
    
    # Collect some texts for later
    slem_texts = {
        cv2.MORPH_RECT: 'Rectangular SLEM',
        cv2.MORPH_ELLIPSE: 'Ellipsoid SLEM',
        cv2.MORPH_CROSS: 'Cross SLEM'
    }
    
    # Collect images
    images = [...]
    
    # Set up maximum values for each slider
    max_morph = len(morphs) - 1
    max_slem = len(slems) - 1
    max_ks = 21
    
    # Set up initial values for each slider
    morph = 0
    slem = 0
    ks = 1
    
    # Set up initial working image
    temp = None
    
    # Set up initial window name
    title_window = 'Interactive {} with {}'.format(morph_texts[morphs[morph]],
                                                   slem_texts[slems[slem]])
    
    
    # Triggered when any slider is manipulated
    def on_trackbar(unused):
        global image, ks, morph, slem, temp, title_window
    
        # Get current slider values
        morph = cv2.getTrackbarPos('Operation', title_window)
        slem = cv2.getTrackbarPos('SLEM', title_window)
        ks = cv2.getTrackbarPos('Kernel size', title_window)
    
        # Reset window name
        cv2.setWindowTitle(title_window, 'Interactive {} with {}'.
                           format(morph_texts[morphs[morph]],
                                  slem_texts[slems[slem]]))
    
        # Get current morphological operation and structuring element
        op = morphs[morph]
        sl = cv2.getStructuringElement(slems[slem], (ks, ks))
    
        # Actual morphological operation
        temp = cv2.morphologyEx(image.copy(), op, sl)
    
        # Show manipulated image with current settings
        cv2.imshow(title_window, temp)
    
    
    # Iterate images
    for image in images:
    
        # Here go your steps before the interactive part
        # ...
        image = cv2.threshold(cv2.cvtColor(image.copy(), cv2.COLOR_BGR2GRAY),
                              0, 255, cv2.THRESH_OTSU)[1]
    
        # Here starts the interactive part
        cv2.namedWindow(title_window)
        cv2.createTrackbar('Operation', title_window, morph, max_morph, on_trackbar)
        cv2.createTrackbar('SLEM', title_window, slem, max_slem, on_trackbar)
        cv2.createTrackbar('Kernel size', title_window, ks, max_ks, on_trackbar)
        cv2.setTrackbarMin('Kernel size', title_window, 1)
        on_trackbar(0)
    
        k = cv2.waitKey(0)
    
        # Exit everytime on pressing q
        while k != ord('q'):
    
            # Save image on pressing s
            if k == ord('s'):
    
                # Here go your steps after the interactive part, but before saving
                # ...
    
                filename = '{} {} {}.png'.\
                    format(morph_texts[morphs[morph]],
                           slem_texts[slems[slem]],
                           ks).replace(' ', '_')
                cv2.imwrite(filename, temp)
                print('Saved image as {}.'.format(filename))
    
            # Go to next image on pressing n
            elif k == ord('n'):
                print('Next image')
                break
    
            # Continue if any other key was pressed
            k = cv2.waitKey(0)
    
        # Actual exiting
        if k == ord('q'):
            break
    

    希望代码是不言自明的。如果没有,请不要犹豫,提出问题。您应该能够轻松添加您自己额外需要的每个滑块,例如对于filters.unsharp_mask 的东西。

    ----------------------------------------
    System information
    ----------------------------------------
    Platform:      Windows-10-10.0.16299-SP0
    Python:        3.9.1
    OpenCV:        4.5.1
    ----------------------------------------
    

    【讨论】:

    • 非常感谢!其实都是我一个人做的。太多的工作。但是你这个人太花哨了。需要您 rcode 进行修订。只有一个问题,如果我想应用腐蚀或膨胀左右,我应该在我的代码中哪里使用它?在sharpenThreshold 之间或divisionsharpen 之间?
    • 对于您的实际问题,这更像是一个语义问题,参见。您链接的原始问题。老实说,我还没有评论过,所以我很抱歉,我不能在这里给出任何建议。
    • 哦,好的!还有一件事,如何更改namedWindow 的大小。我使用了不同的标志,但是当我使用全屏时,我无法调整为更小的尺寸。此外,当我使用相同的窗口显示图像和跟踪栏时,我的图像尺寸会很奇怪,因为我的图像尺寸不同,无法放入窗口。
    • 是的,在使用轨迹栏时这很烦人,但高级 GUI API 仅用于快速原型设计。您可以尝试cv2.resizeWindow,但根据您的系统,某些标志可能有效,而另一些则无效。不幸的是,就是这样。
    • 所以你的意思是说没有办法恢复那个小尺寸的面板?无论我使用哪个标志,它都会是全尺寸的?可以举个例子吗?
    猜你喜欢
    • 2014-03-26
    • 1970-01-01
    • 2019-04-08
    • 1970-01-01
    • 2015-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多