scikit-image threshold_multiotsu 从视频输出黑帧

scikit-image threshold_multiotsu outputting black frames from video

我目前正在开展一个项目,该项目接收视频文件,将各个帧读取为灰度,对其进行归一化、设置阈值,然后将它们输出为单独的 .jpg 文件。下面我有两个函数,frameCapture()frameCaptureMulti()。前者使用 cv2.thresholdcv2.THRESH_OTSU 并按预期工作。后者使用 skimage.filters 中的 threshold_multiotsu() 并输出全黑帧。

import cv2
import numpy as np
from skimage.filters import threshold_multiotsu
def frameCapture(fc_path):
    fc_vidObj = cv2.VideoCapture(fc_path) # Path to video file
    fc_count = 0                          # Used as counter variable
    fc_success = 1                        # Checks if the frames were extracted

    while fc_success:
        # vidObj object calls read
        fc_success, fc_image = fc_vidObj.read()
        fc_image = cv2.cvtColor(fc_image, cv2.COLOR_BGR2GRAY) # Convert the image to grayscale
        fc_image = cv2.GaussianBlur(fc_image,(5,5),0) # Gaussian noise filtering
        (threshold, fc_image) = cv2.threshold(fc_image, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU) # Normalize & Segment
        cv2.imwrite("frame%d.jpg" % fc_count, fc_image) # Saves the frames
        fc_count += 1
def frameCaptureMulti(fc_path):
    fc_vidObj = cv2.VideoCapture(fc_path) # Path to video file
    fc_count = 0                          # Used as counter variable
    fc_success = 1                        # Checks if the frames were extracted

    while fc_success:
        # vidObj object calls read
        fc_success, fc_image = fc_vidObj.read()
        fc_image = cv2.cvtColor(fc_image, cv2.COLOR_BGR2GRAY) # Convert the image to grayscale
        fc_image = cv2.GaussianBlur(fc_image,(5,5),0) # Gaussian noise filtering
        fc_thresholds = threshold_multiotsu(fc_image)
        fc_regions = np.digitize(fc_image, bins=fc_thresholds)
        cv2.imwrite("frame%d.jpg" % fc_count, fc_regions) # Saves the frames
        fc_count += 1

驱动程序代码只是在我计算机上的 .mp4 文件上运行 frameCaptureMulti()。

框架如下所示:
frameCapture() 输出

frameCaptureMulti() 输出:

我不确定为什么 frameCaptureMulti() 会产生纯黑帧。我只有几周的 Python 经验(除了大约十年前的学习经验),而使用这些特定库的经验就更少了,所以欢迎任何关于为什么我的代码没有产生预期输出的帮助。

frameCapture 和 frameCaptureMulti 中部分代码引用的页面:
https://scikit-image.org/docs/dev/auto_examples/segmentation/plot_multiotsu.html
https://www.geeksforgeeks.org/python-program-extract-frames-using-opencv/

我认为发生的事情是 CV2 为您提供了一个二值图像,该图像被正确保存为帧,阈值以下为 0,阈值以上为 255(白色)。同时,threshold_multiotsunp.digitize return 值为 0、1、2 的图像,它们在 jpeg 支持的 0-255 范围内看起来都是黑色的。您可以使用 skimage.exposure.rescale_intensity 将这些值映射到例如0, 127, 255.