Python OpenCV 视频图像熵的奇怪结果
Python OpenCV Strange result for image entropy on video
我正在从事一个项目,旨在使用不同的概念从 mp4 视频中提取“有趣”的序列。
其中一个应该是图像熵,现在,我有点卡住了。
我已经按照本教程从视频中获取了一些选定屏幕截图的熵:
https://scikit-image.org/docs/dev/auto_examples/filters/plot_entropy.html
为此,我得到了如下结果
this one 这就是我想要的。
为了将其应用于我的测试视频,我执行了以下操作:
import cv2
from skimage.filters.rank import entropy
from skimage.morphology import disk
# Creating a VideoCapture object to read the video
video = cv2.VideoCapture('mypath/samplevideo.mp4')
if not video.isOpened():
print("Error reading video file")
width = int(video.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(video.get(cv2.CAP_PROP_FRAME_HEIGHT))
size = (width, height)
fourcc = cv2.VideoWriter_fourcc(*'XVID')
result = cv2.VideoWriter('filename.avi', cv2.VideoWriter_fourcc(*'VIDX'), 30, size)
# Loop until the end of the video
while video.isOpened():
# Capture frame-by-frame
ret, frame = video.read()
# Display the resulting frame
cv2.imshow('Frame', frame)
# apply the entropy to each frame
img = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
entropy_frame = entropy(img, disk(5))
cv2.imshow('Entropy', entropy_frame)
result.write(entropy_frame)
# define q as the exit button
if cv2.waitKey(25) & 0xFF == ord('q'):
break
# release the video capture object
video.release()
result.release()
# Closes all the windows currently opened.
cv2.destroyAllWindows()
此代码生成两个 windows,一个包含原始视频(根据需要),另一个应该显示相同的视频但应用了图像熵。最后,它应该保存熵视频。我现在在“熵 window”中得到的是 something like this (left is the original video, right the entropy),它看起来根本不像我想要的结果。
我可以修正什么以获得我想要的结果?
提前致谢
你得到了奇怪的结果,因为 entropy_frame
的范围大约是 [0, 6.0]。
您需要将范围转换为 [0, 255] 并将结果从 float
转换为 uint8
.
进行范围转换的一种简单方法是乘以 (255/max(entropy_mat)
):
entropy_frame = (entropy_mat * 255/np.max(entropy_mat)).astype(np.uint8)
注:
example使用matplotlib方法ax1.imshow
,自动进行线性拉伸显示,所以显示正确(但不能作为视频帧使用)。
这里是一个单帧的例子:
import numpy as np
import cv2
from skimage.filters.rank import entropy
from skimage.morphology import disk
frame = cv2.imread('frame.png')
# Display the resulting frame
cv2.imshow('Frame', frame)
# apply the entropy to each frame
img = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
entropy_mat = entropy(img, disk(5)) # Range is about [0, 6]
# Apply linear stretching - lower 1% goes to 0, and maximum 1% goes to 255
# lo_val, up_val = np.percentile(entropy_mat, (1, 99)) # Get the value of lower and upper 1% of all pixels [0, 5.48]
#
# entropy_frame = np.clip((entropy_mat - lo_val)*(255/(up_val - lo_val)), 0, 255).astype(np.uint8)
# Or simply multiply by 255/np.max(entropy_mat)
entropy_frame = (entropy_mat * 255/np.max(entropy_mat)).astype(np.uint8)
cv2.imshow('Entropy', entropy_frame)
cv2.imwrite('entropy_frame.png', entropy_frame)
cv2.waitKey()
cv2.destroyAllWindows()
备注:
修改cv2.VideoWriter_fourcc(*'VIDX')
为cv2.VideoWriter_fourcc(*'XVID')
('VIDX'显示错误信息)
entropy_frame
是灰度图像。
您需要将 VideoWriter isColor
参数设置为 False
:
result = cv2.VideoWriter('filename.avi', cv2.VideoWriter_fourcc(*'VIDX'), 30, size, isColor=False)
如果 ret
是 False
,您需要打破循环:
if not ret:
break
结果:
完整代码:
import numpy as np
import cv2
from skimage.filters.rank import entropy
from skimage.morphology import disk
# Creating a VideoCapture object to read the video
video = cv2.VideoCapture('mypath/samplevideo.mp4')
if not video.isOpened():
print("Error reading video file")
width = int(video.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(video.get(cv2.CAP_PROP_FRAME_HEIGHT))
size = (width, height)
fourcc = cv2.VideoWriter_fourcc(*'XVID')
result = cv2.VideoWriter('filename.avi', cv2.VideoWriter_fourcc(*'XVID'), 30, size, isColor=False)
# Loop until the end of the video
while video.isOpened():
# Capture frame-by-frame
ret, frame = video.read()
if not ret:
break # Break the loop if ret is false (last video frame).
# Display the resulting frame
cv2.imshow('Frame', frame)
# apply the entropy to each frame
img = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
entropy_mat = entropy(img, disk(5))
entropy_frame = (entropy_mat * 255/np.max(entropy_mat)).astype(np.uint8)
cv2.imshow('Entropy', entropy_frame)
result.write(entropy_frame)
# define q as the exit button
if cv2.waitKey(25) & 0xFF == ord('q'):
break
# release the video capture object
video.release()
result.release()
# Closes all the windows currently opened.
cv2.destroyAllWindows()
我正在从事一个项目,旨在使用不同的概念从 mp4 视频中提取“有趣”的序列。
其中一个应该是图像熵,现在,我有点卡住了。
我已经按照本教程从视频中获取了一些选定屏幕截图的熵: https://scikit-image.org/docs/dev/auto_examples/filters/plot_entropy.html
为此,我得到了如下结果 this one 这就是我想要的。
为了将其应用于我的测试视频,我执行了以下操作:
import cv2
from skimage.filters.rank import entropy
from skimage.morphology import disk
# Creating a VideoCapture object to read the video
video = cv2.VideoCapture('mypath/samplevideo.mp4')
if not video.isOpened():
print("Error reading video file")
width = int(video.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(video.get(cv2.CAP_PROP_FRAME_HEIGHT))
size = (width, height)
fourcc = cv2.VideoWriter_fourcc(*'XVID')
result = cv2.VideoWriter('filename.avi', cv2.VideoWriter_fourcc(*'VIDX'), 30, size)
# Loop until the end of the video
while video.isOpened():
# Capture frame-by-frame
ret, frame = video.read()
# Display the resulting frame
cv2.imshow('Frame', frame)
# apply the entropy to each frame
img = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
entropy_frame = entropy(img, disk(5))
cv2.imshow('Entropy', entropy_frame)
result.write(entropy_frame)
# define q as the exit button
if cv2.waitKey(25) & 0xFF == ord('q'):
break
# release the video capture object
video.release()
result.release()
# Closes all the windows currently opened.
cv2.destroyAllWindows()
此代码生成两个 windows,一个包含原始视频(根据需要),另一个应该显示相同的视频但应用了图像熵。最后,它应该保存熵视频。我现在在“熵 window”中得到的是 something like this (left is the original video, right the entropy),它看起来根本不像我想要的结果。
我可以修正什么以获得我想要的结果? 提前致谢
你得到了奇怪的结果,因为 entropy_frame
的范围大约是 [0, 6.0]。
您需要将范围转换为 [0, 255] 并将结果从 float
转换为 uint8
.
进行范围转换的一种简单方法是乘以 (255/max(entropy_mat)
):
entropy_frame = (entropy_mat * 255/np.max(entropy_mat)).astype(np.uint8)
注:
example使用matplotlib方法ax1.imshow
,自动进行线性拉伸显示,所以显示正确(但不能作为视频帧使用)。
这里是一个单帧的例子:
import numpy as np
import cv2
from skimage.filters.rank import entropy
from skimage.morphology import disk
frame = cv2.imread('frame.png')
# Display the resulting frame
cv2.imshow('Frame', frame)
# apply the entropy to each frame
img = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
entropy_mat = entropy(img, disk(5)) # Range is about [0, 6]
# Apply linear stretching - lower 1% goes to 0, and maximum 1% goes to 255
# lo_val, up_val = np.percentile(entropy_mat, (1, 99)) # Get the value of lower and upper 1% of all pixels [0, 5.48]
#
# entropy_frame = np.clip((entropy_mat - lo_val)*(255/(up_val - lo_val)), 0, 255).astype(np.uint8)
# Or simply multiply by 255/np.max(entropy_mat)
entropy_frame = (entropy_mat * 255/np.max(entropy_mat)).astype(np.uint8)
cv2.imshow('Entropy', entropy_frame)
cv2.imwrite('entropy_frame.png', entropy_frame)
cv2.waitKey()
cv2.destroyAllWindows()
备注:
修改
cv2.VideoWriter_fourcc(*'VIDX')
为cv2.VideoWriter_fourcc(*'XVID')
('VIDX'显示错误信息)entropy_frame
是灰度图像。
您需要将 VideoWriterisColor
参数设置为False
:result = cv2.VideoWriter('filename.avi', cv2.VideoWriter_fourcc(*'VIDX'), 30, size, isColor=False)
如果
ret
是False
,您需要打破循环:if not ret: break
结果:
完整代码:
import numpy as np
import cv2
from skimage.filters.rank import entropy
from skimage.morphology import disk
# Creating a VideoCapture object to read the video
video = cv2.VideoCapture('mypath/samplevideo.mp4')
if not video.isOpened():
print("Error reading video file")
width = int(video.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(video.get(cv2.CAP_PROP_FRAME_HEIGHT))
size = (width, height)
fourcc = cv2.VideoWriter_fourcc(*'XVID')
result = cv2.VideoWriter('filename.avi', cv2.VideoWriter_fourcc(*'XVID'), 30, size, isColor=False)
# Loop until the end of the video
while video.isOpened():
# Capture frame-by-frame
ret, frame = video.read()
if not ret:
break # Break the loop if ret is false (last video frame).
# Display the resulting frame
cv2.imshow('Frame', frame)
# apply the entropy to each frame
img = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
entropy_mat = entropy(img, disk(5))
entropy_frame = (entropy_mat * 255/np.max(entropy_mat)).astype(np.uint8)
cv2.imshow('Entropy', entropy_frame)
result.write(entropy_frame)
# define q as the exit button
if cv2.waitKey(25) & 0xFF == ord('q'):
break
# release the video capture object
video.release()
result.release()
# Closes all the windows currently opened.
cv2.destroyAllWindows()