scikit-image threshold_multiotsu 从视频输出黑帧
scikit-image threshold_multiotsu outputting black frames from video
我目前正在开展一个项目,该项目接收视频文件,将各个帧读取为灰度,对其进行归一化、设置阈值,然后将它们输出为单独的 .jpg 文件。下面我有两个函数,frameCapture()
和 frameCaptureMulti()
。前者使用 cv2.threshold
和 cv2.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_multiotsu
和 np.digitize
return 值为 0、1、2 的图像,它们在 jpeg 支持的 0-255 范围内看起来都是黑色的。您可以使用 skimage.exposure.rescale_intensity
将这些值映射到例如0, 127, 255.
我目前正在开展一个项目,该项目接收视频文件,将各个帧读取为灰度,对其进行归一化、设置阈值,然后将它们输出为单独的 .jpg 文件。下面我有两个函数,frameCapture()
和 frameCaptureMulti()
。前者使用 cv2.threshold
和 cv2.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_multiotsu
和 np.digitize
return 值为 0、1、2 的图像,它们在 jpeg 支持的 0-255 范围内看起来都是黑色的。您可以使用 skimage.exposure.rescale_intensity
将这些值映射到例如0, 127, 255.