mil*_*azs 5 python video opencv image-processing ravi
什么ravi文件是:
RAVI文件是由热成像软件(例如Micro-Epsilon TIM Connect或Optris PIX Connect)创建的视频文件。它包含由热像仪捕获的视频,并以类似于音频视频交错(.AVI)格式的格式保存。RAVI文件还存储辐射度信息,例如由热像仪收集的温度和测量区域信息。
我的问题:
我必须处理ravi文件中的数据。我需要像素的温度值(或者帧的最高温度足以满足我的需要)。我想检查特定框架上的最高温度。最终结果将是一个报告,其中包含框架上的最高温度值(这将是图形)。使用Micro-Epsilon TIM Connect或Optris PIX Connect工具很容易检查和处理,但是我无法使用它们(我必须编写自己的工具)。
我的问题:
ravi文件中获取数据(实际上我只需要温度值)?ravi文件转换为另一个文件(如果我可以从ravi文件中获取数据,这无关紧要)?注意:
ravi文件,但无法记录新文件或修改记录。SDK此类相机的站点,但对我来说不清楚ravi是否可以从文件中获取数据。链接到libirimager2文档:libirimager2ravi使用媒体播放器播放文件,则说明使用的编解码器为:(Uncompressed packed YUV 4:2:2您可以在下面看到获取流)如果我OpenCV用媒体播放器解析它或在其中播放,则可以看到一些信息流。但是我不确定如何获得温度...
CV2代码:
import cv2
cap = cv2.VideoCapture("my_test.ravi")
if not cap.isOpened():
print("Error opening video stream or file")
while cap.isOpened():
ret, frame = cap.read()
if ret:
cv2.imshow('Frame', frame)
if cv2.waitKey(25) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
Run Code Online (Sandbox Code Playgroud)
正在流式传输:
(我在一个简单的媒体播放器中也看到了相同的“粉红色和绿色”流。)
在官方软件中流式传输:
ravi HexEditor中的文件:
我找到了一个有关AVI视频格式的网站。您可以从我的文件乞求下面看到几行,也许可以帮上忙。
00000000 52 49 46 46 F8 B1 C6 3F 41 56 49 20 4C 49 53 54 RIFF...?AVI LIST
00000010 CC 7F 00 00 68 64 72 6C 61 76 69 68 38 00 00 00 ....hdrlavih8...
00000020 12 7A 00 00 44 FF DD 00 00 02 00 00 10 08 00 00 .z..D...........
00000030 44 6D 00 00 00 00 00 00 01 00 00 00 08 65 09 00 Dm...........e..
00000040 80 02 00 00 E1 01 00 00 00 00 00 00 00 00 00 00 ................
00000050 00 00 00 00 00 00 00 00 4C 49 53 54 74 7E 00 00 ........LISTt~..
00000060 73 74 72 6C 73 74 72 68 38 00 00 00 76 69 64 73 strlstrh8...vids
00000070 59 55 59 32 00 00 00 00 00 00 00 00 00 00 00 00 YUY2............
00000080 B4 C4 04 00 80 96 98 00 00 00 00 00 A4 50 00 00 .............P..
00000090 08 65 09 00 00 00 00 00 00 00 00 00 00 00 00 00 .e..............
000000A0 00 00 00 00 73 74 72 66 28 00 00 00 28 00 00 00 ....strf(...(...
000000B0 80 02 00 00 E1 01 00 00 01 00 10 00 59 55 59 32 ............YUY2
000000C0 00 65 09 00 60 00 00 00 60 00 00 00 00 00 00 00 .e..`...`.......
000000D0 00 00 00 00 69 6E 64 78 F8 7D 00 00 04 00 00 00 ....indx.}......
000000E0 06 00 00 00 30 30 64 62 00 00 00 00 00 00 00 00 ....00db........
Run Code Online (Sandbox Code Playgroud)
测试材料:
如果您PIX Connect Rel. 3.6.3046.0 Software从http://infrarougekelvin.com/en/optris-logiciel-eng/网站下载,则可以ravi在zip的“ Samples”文件夹中找到几个文件。
官方文档中的其他信息:
视频序列既可以保存为辐射文件(RAVI),也可以保存为非辐射文件(AVI)。RAVI文件包含所有温度以及测量区域信息。
如果是辐射记录,请参见第15章。5.6.2,未激活的图像将被保存为仅包含颜色信息的标准AVI文件。以后无法将RAVI文件转换为AVI文件,反之亦然
更新:
我试图使用该PyAV模块来获取数据。该模块能够处理yuyv422格式。我得到相同的“绿粉红色”流,但无法从中获得温度...
使用的代码:
# coding=utf-8
import av
import os
ravi_path = "Brake disc.ravi"
container = av.open(ravi_path)
stream = container.streams.video[0]
stream.codec_context.skip_frame = 'NONKEY'
tgt_path = "frames"
if not os.path.isdir(tgt_path):
os.makedirs(tgt_path)
for frame in container.decode(stream):
tgt_filename = os.path.join(tgt_path, 'frame-{:09d}.jpg'.format(frame.pts))
print(frame, tgt_filename)
frame.to_image().save(tgt_filename, quality=80)
Run Code Online (Sandbox Code Playgroud)
脚本的输出:
>>> python ravi_test2.py
(<av.VideoFrame #0, pts=0 yuyv422 160x121 at 0x7f501bfa8598>, 'frames/frame-000000000.jpg')
(<av.VideoFrame #1, pts=1 yuyv422 160x121 at 0x7f501bfa8600>, 'frames/frame-000000001.jpg')
(<av.VideoFrame #2, pts=2 yuyv422 160x121 at 0x7f5018e0fdb8>, 'frames/frame-000000002.jpg')
(<av.VideoFrame #3, pts=3 yuyv422 160x121 at 0x7f501bfa8598>, 'frames/frame-000000003.jpg')
(<av.VideoFrame #4, pts=4 yuyv422 160x121 at 0x7f501bfa8600>, 'frames/frame-000000004.jpg')
(<av.VideoFrame #5, pts=5 yuyv422 160x121 at 0x7f5018e0fdb8>, 'frames/frame-000000005.jpg')
Run Code Online (Sandbox Code Playgroud)
我不知道您的相机品牌,但期望视频文件包含 16 位无符号整数形式的原始传感器值,这可能只是在视频标头中命名为 YUV422,因为它们适合相同的每像素 16 位。
您可以通过特定的非线性校准曲线将这些值转换为实际温度值。如果 RAVI 格式是单一文件格式(与某些具有原始 AVI + 校准表的传统红外摄像机相反),那么您应该找到构成方程的几个浮点常数和/或表的位置。
可以对逻辑进行逆向工程,但最好向制造商询问正确的方程式。例如,您在互联网上找到的内容可能只是校准曲线的旧版本。大多数制造商随其设备提供校准库。一些超出产品周期的设备可能很难谈判,但您至少应该获得一份有关该主题的白皮书。
如果您使用 OpenCV,则需要读取 YUV422 帧原始数据(16bpp,而不是 24bpp),并在应用查找表之前将其上下文重新解释为 uint16。
// sample C++ code employing private content of OpenCV library
// Particularly container_avi.private.hpp and container_avi.cpp
void mainactual()
{
cv::AVIReadContainer reader;
reader.initStream(cv::String("C:/tello/intro2.avi"));
cv::frame_list frames;
// initializes the stream
reader.parseRiff( frames );
std::cout << "Number of frames: " << frames.size() << std::endl;
int w=reader.getWidth();
int h=reader.getHeight();
std::cout << "size " << cv::Size(w,h) << std::endl;
// a frame in the middle
cv::frame_iterator it=frames.begin() + frames.size()/2;
std::vector< char> data = reader.readFrame( it );
// In your case, data here is supposed to be
// uncompressed YUV422 which is w * h * 2 bytes per frame
// You might need to modify
// bool AVIReadContainer::parseStrl(char stream_id, Codecs codec_)
// to accept your FCC
//
//
//if ( data.size()!=w*h*2 )
//{
// // error
//}
// My video is MJPEG, so I'm confident to just to decode it
cv::Mat img = cv::imdecode( data, cv::IMREAD_UNCHANGED );
cv::imshow("image", img ); // looks fine
cv::waitKey( 0 );
reader.close();
}
Run Code Online (Sandbox Code Playgroud)
编辑:经过测试的制动盘.ravi,如下所示。修改了解析器以接受未压缩的 YUV2 格式,并根据https://learn.microsoft.com/en-us/previous-versions/windows/desktop/api/Aviriff/ns-aviriff-avioldindex添加了一个 hack
dw偏移量
指定文件中数据块的位置。该值应指定为从“movi”列表开头的偏移量(以字节为单位);然而,在某些 AVI 文件中,它是以距文件开头的偏移量形式给出的。
cv::Mat img;
if ( data.size()==w*h*2 )
{
std::cout << data.size() << " " << w*h*2 << std::endl;
cv::Mat t( h, w, CV_16UC1, &data[0] );
// img(y,x) = (float)t(y,x)/10.0 - 100.0
t.convertTo( img, CV_32F, 0.1, -100.0 );
}else
return;
double mi,ma;
cv::minMaxLoc( img, &mi, &ma );
std::cout << "range: [" << mi << ", " << ma << "]" << std::endl;
cv::Mat gray;
img.convertTo( gray, CV_8U ); // [0, 255] range saturated
cv::Mat bigger;
cv::resize(gray,bigger,cv::Size(4*w,4*h),0,0,cv::INTER_LINEAR );
cv::Mat jet;
cv::applyColorMap( bigger, jet, cv::COLORMAP_JET );
cv::imshow("image", jet ); // looks fine
cv::waitKey( 0 );
reader.close();
Run Code Online (Sandbox Code Playgroud)