Matlab中从.ravi文件中提取温度

Matlab中从.ravi文件中提取温度,matlab,video,ravi,Matlab,Video,Ravi,我的问题 很像这里的帖子:,我有一个.ravi文件(一个辐射测量视频文件,非常类似于.avi),我试图提取其中的温度,将其与其他传感器数据一起使用 下载“PIX Connect软件”时,可以在文档()中找到示例文件。不幸的是,根据文档,温度信息是以16位格式存储的,Matlab似乎对此相当不满意 我是如何解决我的问题的 我试着按照前面提到的帖子中的说明去做,但不知怎么的,我很难得到结果,甚至接近正确的温度 我试着用不同的方法阅读视频: 起初,我希望使用Matlab中的录像机功能: video

我的问题

很像这里的帖子:,我有一个.ravi文件(一个辐射测量视频文件,非常类似于.avi),我试图提取其中的温度,将其与其他传感器数据一起使用

下载“PIX Connect软件”时,可以在文档()中找到示例文件。不幸的是,根据文档,温度信息是以16位格式存储的,Matlab似乎对此相当不满意

我是如何解决我的问题的

我试着按照前面提到的帖子中的说明去做,但不知怎么的,我很难得到结果,甚至接近正确的温度

我试着用不同的方法阅读视频: 起初,我希望使用Matlab中的
录像机
功能:

video   = VideoReader(videoPath);
frame1  = video.read(1);
imagesc(frame1)
但这只会导致这张糟糕的图片,这正是我在vlc这样的媒体播放器中播放.ravi文件时看到的

然后我试着查看文件的二进制表示,注意到我可以在某个标记处分离帧

因此,我尝试使用matlab
fread
函数读取该文件:

fileID               = fopen(videoPath);    
[headerInfo,~]       = fread(fileID,[1,123392],'uint8');
[imageMatrix,count]  = fread(fileID,[video.width, video.height],'uint16', 'b');
imagesc(imageMatrix')
现在,图像看起来更好了,你至少可以看到制动盘,但似乎更高的温度有某种偏移,这仍然是缺失的,因为图像是正确的

另外,我从文件中读取的值与实际温度相差甚远,正如另一篇文章和文档所示

我的问题


我是不是错过了什么重要的东西?有没有人能告诉我正确的方向,去哪里看,或者如何从我的视频中获取实际温度?由于它在另一篇文章中使用了cpp代码,我猜这可能是matlab的问题。

获取原始帧数据的一个相对简单的解决方案是将RAVI视频文件转换为原始视频文件格式

您可以使用(命令行工具)将RAVI转换为原始格式

例如:

ffmpeg -y -f avi -i "Sequence_LED_Holder.ravi" -vcodec rawvideo "Sequence_LED_Holder.yuv"
YUV(原始二进制数据)文件可以通过MATLAB使用
fread
函数简单地读取。
注意:
.yuv
只是原始视频文件的约定(FFmpeg使用)-实际像素格式不是yuv,而是int16格式

您可以尝试手动解析RAVI文件,但使用FFmpeg要简单得多

原始文件格式由一个接一个没有标题的原始视频帧组成。
在我们的例子中,每个帧是
宽度*高度*2
字节。
像素类型为
int16
(可能包括负值)

红外视频帧没有颜色信息。
这些颜色只是使用调色板创建的用于可视化的“假颜色”。
代码示例使用来自不同红外相机制造商的调色板

获取温度:
我无法找到将像素值转换为等效温度的方法。
我没有阅读文档-有可能在某个地方记录了转换


MATLAB代码示例应用于以下阶段:

  • 使用FFmpeg将RAVI文件格式转换为原始视频文件格式
  • 将视频帧读取为
    [cols,rows]
    size
    int16
    matrix
  • 删除可能包含数据(而不是像素)的第一行
  • 使用线性对比度拉伸-进行可视化
  • 应用假颜色-用于可视化
  • 显示处理后的视频帧
以下是代码示例:

%ravi_file_name = 'Brake disc.ravi';
%ravi_file_name = 'Combustion process.ravi';
%ravi_file_name = 'Electronic board.ravi';
%ravi_file_name = 'Sequence_carwheels.ravi';
%ravi_file_name = 'Sequence_drop.ravi';
ravi_file_name = 'Sequence_LED_Holder.ravi';
%ravi_file_name = 'Steel workpiece with hole.ravi';

yuv_file_name = strrep(ravi_file_name, '.ravi', '.yuv'); % Same file name with .yuv extension.

% Get video resolution.
vidinfo = mmfileinfo(ravi_file_name);
cols = vidinfo.Video.Width;
rows = vidinfo.Video.Height;


% Execute ffmpeg (in the system shell) for converting RAVI to raw data file.
% Remark: download FFmpeg if needed, and make sure ffmpeg executable is in the execution path.
if ~exist(yuv_file_name, 'file')
    % Remark: For some of the video files, cmdout returns a string with lots of meta-data 
    [status, cmdout] = system(sprintf('ffmpeg -y -f avi -i "%s" -vcodec rawvideo "%s"', ravi_file_name, yuv_file_name));
    if (status ~= 0)
        fprintf(cmdout);
        error(['Error: ffmpeg status = ', num2str(status)]);
    end
end

% Get the number of frames according to file size.
filesize = getfield(dir(yuv_file_name), 'bytes');
n_frames = filesize / (cols*rows*2);

f = fopen(yuv_file_name, 'r');

% Iterate the frames (skip the last frame).
for i = 1:n_frames-1
    % Read frame as cols x rows and int16 type.
    % The data is signed (int16) and not uint16.
    I = fread(f, [cols, rows], '*int16')';
  
    % It looks like the first line contains some data (not pixels).
    data_line = I(1, :);
    I = I(2:end, :);
    
    % Apply linear stretch - in order to "see something"...
    J = imadjust(I, stretchlim(I, [0.02, 0.98]));
    
    % Apply false colors - just for visualization.
    K = ColorizeIr(J);

    if (i == 1)
        figure;
        h = imshow(K, []); %h = imshow(J, []);
        impixelinfo
    else
        if ~isvalid(h)
            break;
        end
        h.CData = K; %h.CData = J;
    end
    
    pause(0.05);
end

fclose(f);

imwrite(uint16(J+2^15), 'J.tif'); % Write J as uint16 image.
imwrite(K, 'K.png'); % Write K image (last frame).



% Colorize the IR video frame with "false colors".
function J = ColorizeIr(I)
    % The palette apply different IR manufacture - don't expect the result to resemble OPTRIS output.
    % https://groups.google.com/g/flir-lepton/c/Cm8lGQyspmk
    colormapIronBlack = uint8([...
        255, 255, 255, 253, 253, 253, 251, 251, 251, 249, 249, 249, 247, 247,...
        247, 245, 245, 245, 243, 243, 243, 241, 241, 241, 239, 239, 239, 237,...
        237, 237, 235, 235, 235, 233, 233, 233, 231, 231, 231, 229, 229, 229,...
        227, 227, 227, 225, 225, 225, 223, 223, 223, 221, 221, 221, 219, 219,...
        219, 217, 217, 217, 215, 215, 215, 213, 213, 213, 211, 211, 211, 209,...
        209, 209, 207, 207, 207, 205, 205, 205, 203, 203, 203, 201, 201, 201,...
        199, 199, 199, 197, 197, 197, 195, 195, 195, 193, 193, 193, 191, 191,...
        191, 189, 189, 189, 187, 187, 187, 185, 185, 185, 183, 183, 183, 181,...
        181, 181, 179, 179, 179, 177, 177, 177, 175, 175, 175, 173, 173, 173,...
        171, 171, 171, 169, 169, 169, 167, 167, 167, 165, 165, 165, 163, 163,...
        163, 161, 161, 161, 159, 159, 159, 157, 157, 157, 155, 155, 155, 153,...
        153, 153, 151, 151, 151, 149, 149, 149, 147, 147, 147, 145, 145, 145,...
        143, 143, 143, 141, 141, 141, 139, 139, 139, 137, 137, 137, 135, 135,...
        135, 133, 133, 133, 131, 131, 131, 129, 129, 129, 126, 126, 126, 124,...
        124, 124, 122, 122, 122, 120, 120, 120, 118, 118, 118, 116, 116, 116,...
        114, 114, 114, 112, 112, 112, 110, 110, 110, 108, 108, 108, 106, 106,...
        106, 104, 104, 104, 102, 102, 102, 100, 100, 100, 98, 98, 98, 96, 96,...
        96, 94, 94, 94, 92, 92, 92, 90, 90, 90, 88, 88, 88, 86, 86, 86, 84, 84,...
        84, 82, 82, 82, 80, 80, 80, 78, 78, 78, 76, 76, 76, 74, 74, 74, 72, 72,...
        72, 70, 70, 70, 68, 68, 68, 66, 66, 66, 64, 64, 64, 62, 62, 62, 60, 60,...
        60, 58, 58, 58, 56, 56, 56, 54, 54, 54, 52, 52, 52, 50, 50, 50, 48, 48,...
        48, 46, 46, 46, 44, 44, 44, 42, 42, 42, 40, 40, 40, 38, 38, 38, 36, 36,...
        36, 34, 34, 34, 32, 32, 32, 30, 30, 30, 28, 28, 28, 26, 26, 26, 24, 24,...
        24, 22, 22, 22, 20, 20, 20, 18, 18, 18, 16, 16, 16, 14, 14, 14, 12, 12,...
        12, 10, 10, 10, 8, 8, 8, 6, 6, 6, 4, 4, 4, 2, 2, 2, 0, 0, 0, 0, 0, 9,...
        2, 0, 16, 4, 0, 24, 6, 0, 31, 8, 0, 38, 10, 0, 45, 12, 0, 53, 14, 0,...
        60, 17, 0, 67, 19, 0, 74, 21, 0, 82, 23, 0, 89, 25, 0, 96, 27, 0, 103,...
        29, 0, 111, 31, 0, 118, 36, 0, 120, 41, 0, 121, 46, 0, 122, 51, 0, 123,...
        56, 0, 124, 61, 0, 125, 66, 0, 126, 71, 0, 127, 76, 1, 128, 81, 1, 129,...
        86, 1, 130, 91, 1, 131, 96, 1, 132, 101, 1, 133, 106, 1, 134, 111, 1,...
        135, 116, 1, 136, 121, 1, 136, 125, 2, 137, 130, 2, 137, 135, 3, 137,...
        139, 3, 138, 144, 3, 138, 149, 4, 138, 153, 4, 139, 158, 5, 139, 163,...
        5, 139, 167, 5, 140, 172, 6, 140, 177, 6, 140, 181, 7, 141, 186, 7,...
        141, 189, 10, 137, 191, 13, 132, 194, 16, 127, 196, 19, 121, 198, 22,...
        116, 200, 25, 111, 203, 28, 106, 205, 31, 101, 207, 34, 95, 209, 37,...
        90, 212, 40, 85, 214, 43, 80, 216, 46, 75, 218, 49, 69, 221, 52, 64,...
        223, 55, 59, 224, 57, 49, 225, 60, 47, 226, 64, 44, 227, 67, 42, 228,...
        71, 39, 229, 74, 37, 230, 78, 34, 231, 81, 32, 231, 85, 29, 232, 88,...
        27, 233, 92, 24, 234, 95, 22, 235, 99, 19, 236, 102, 17, 237, 106, 14,...
        238, 109, 12, 239, 112, 12, 240, 116, 12, 240, 119, 12, 241, 123, 12,...
        241, 127, 12, 242, 130, 12, 242, 134, 12, 243, 138, 12, 243, 141, 13,...
        244, 145, 13, 244, 149, 13, 245, 152, 13, 245, 156, 13, 246, 160, 13,...
        246, 163, 13, 247, 167, 13, 247, 171, 13, 248, 175, 14, 248, 178, 15,...
        249, 182, 16, 249, 185, 18, 250, 189, 19, 250, 192, 20, 251, 196, 21,...
        251, 199, 22, 252, 203, 23, 252, 206, 24, 253, 210, 25, 253, 213, 27,...
        254, 217, 28, 254, 220, 29, 255, 224, 30, 255, 227, 39, 255, 229, 53,...
        255, 231, 67, 255, 233, 81, 255, 234, 95, 255, 236, 109, 255, 238, 123,...
        255, 240, 137, 255, 242, 151, 255, 244, 165, 255, 246, 179, 255, 248,...
        193, 255, 249, 207, 255, 251, 221, 255, 253, 235, 255, 255, 24]);
    
    lutR = colormapIronBlack(1:3:end);
    lutG = colormapIronBlack(2:3:end);
    lutB = colormapIronBlack(3:3:end);
    
    % Convert I to uint8
    I = im2uint8(I);
    R = lutR(I+1);
    G = lutG(I+1);
    B = lutB(I+1);
    
    J = cat(3, R, G, B);
end

示例输出:

我可以向您展示如何读取视频帧,但我不知道如何获取温度,以及如何正确显示帧。你想让我发布答案吗?当然,为什么不?你会用什么方法来读取帧?如果我能得到原始的存储值,我也许能计算出温度,它总是像ffmpeg一样的东西,我没有想到,非常感谢,伙计,这解决了我的问题!我不太关心图片/颜色本身,我想看看原始温度,我现在可以用校准文件计算。你刚刚帮我省了很多工作!我真的很感激!如果有办法在网上给你买啤酒,请告诉我!这是一个需要解决的有趣问题。不要在互联网上给我买啤酒:-)如果你能发布根据原始数据计算温度的方法,我会很高兴的(只要你允许发布,并且愿意分享)。这个方法非常简单。你买的每台相机都有一个校准文件,其中包括一条校准曲线,该曲线将传感器值映射到温度。然后您可以简单地使用interp1,从每个帧获得实际温度。我想我不允许分享文件本身,但它不会有很大的用处,因为它专门用于我们相机中的传感器。