您当前的位置:首页 > 计算机 > 编程开发 > Python

关于图像融合 视频融合

时间:04-17来源:作者:点击数:

图像融合 视频融合

怎么把一张小尺寸图片贴进大尺寸图片里面呢

怎么把一个长和宽小的视频贴进长和宽大点的视频之中呢

下面有两种方法,直接融合和泊松融合

直接融合

图像直接融合

%%图像直接融合
clear
clc
%%读取图像文件
I=double(imread('1.jpg'));
img=double(imread('4.jpg'));
figure(1),imshow(uint8(I));
 
% 直接拼接-------------------
 [row,col,~]=size(img);

%法1 鼠标选择位置
%  [y_start,x_start]=ginput(1);%获得1个鼠标点击位置

%法2 输入位置数据
x_start=100;y_start=10;  %输入坐标(10,100)输入顺序Y,X

x_end=x_start+row-1;
y_end=y_start+col-1;
I(x_start:x_end,y_start:y_end, :)=img(:,:,:);

figure(2);imshow(uint8(I));title('直接拼接图');

图1 鼠标选择位置

图2 融合效果

视频帧直接融合

%视频直接融合
clc
clear
close all;
% addpath(fullfile(pwd, 'picture_ronghe'));
%读取原视频文件
[fastaFile,dirName]=uigetfile({'*.avi;*.mp4;*.rmvb;*.wmv','Video File(*.avi;*.mp4;*.rmvb;*.wmv)';...
    '*.*',  'All Files (*.*)'}, ...
    'Choose a Video File');
[~, name] = fileparts([dirName,fastaFile]);
vid = VideoReader([dirName,fastaFile]);
vid_numFrames = vid.NumFrames;
vid_Frame = read(vid, 1);imshow(vid_Frame),title('第一帧')
%读取放大后的视频
[fastaFile,dirName]=uigetfile({'*.avi;*.mp4;*.rmvb;*.wmv','Video File(*.avi;*.mp4;*.rmvb;*.wmv)';...
    '*.*',  'All Files (*.*)'}, ...
    'Choose a Video File');
[~, name2] = fileparts([dirName,fastaFile]);
vidAmp = VideoReader([dirName,fastaFile]);
vidAmp_numFrames = vidAmp.NumFrames;


outName = fullfile(dirName,[name '_ronghe.avi']);
vidOut = VideoWriter(outName);
vidOut.FrameRate = vid.FrameRate;
open(vidOut)
tic

% for i = 1 : min(vid.NumFrames,vidAmp.NumFrames)
for i = 1 :10
    Frame = read(vid, i);%原视频帧
    FrameAmp = read(vidAmp, i);%放大视频帧 
    I=Frame;img=FrameAmp;

    %法1: 由鼠标选择融合位置
    [y_start,x_start]=ginput(1);%获得1个鼠标点击的位置
    
    %法2:直接输入融合位置坐标
    %输入小视频左上角坐标位置,先输入Y,再输入X。 x_start=Y,y_start=X
%     x_start=217; y_start=418;
    
    [row_img,col_img,~]=size(img);
    x_end=x_start+row_img-1;
    y_end=y_start+col_img-1;
    I(x_start:x_end,y_start:y_end, :)=img(:,:,:);
    writeVideo(vidOut,im2uint8(I));  
end
close(vidOut);
toc
fprintf('视频融合完成\n');

泊松融合

图像泊松融合 函数 create_AB.m

%%图像泊松融合
function [A,B]=create_AB(image_A,mask_A,image_B,mask_B)
%假设插入的图片为方形
%image_A为插入图片
%mask_A为背景图片的模子,待插入部分为0,不插入部分为1
global number
[hxb,lxb,~]=find(mask_B==0);
B=zeros(length(hxb),1);%创建B
s=[hxb';lxb'];
[s1,id1]=sort(s(1,:));
s_z=[s1;s(2,id1)];%将行下标和列下标的顺序整理为行优先
hxb=s_z(1,:);
lxb=s_z(2,:);
min_x=min(hxb);
min_y=min(lxb);
max_x=max(hxb);
max_y=max(lxb);
k=2;
for i=1:length(hxb)
    mask_B(hxb(i),lxb(i))=k;
    k=k+1;
end
if number==1
A=sparse(zeros(length(hxb),length(hxb)));
end
if number~=1
    A=0;
end
k=1;%k为正在填写A矩阵的第k行
for i=min_x:max_x
    for j=min_y:max_y
        if i==min_x||i==max_x||j==min_y||j==max_y
            if number==1%如果第一次运行该求A函数
                A(k,k)=1;
            end
            B(k)=image_B(i,j);%边界点B为其像素值
            k=k+1;
        end
        if i~=min_x && i~=max_x&&j~=min_y&&j~=max_y
            if number ==1
                A(k,mask_B(i-1,j)-1)=1;
                
                A(k,mask_B(i,j-1)-1)=1;
                
                A(k,mask_B(i,j+1)-1)=1;
                
                A(k,mask_B(i+1,j)-1)=1;
                
                A(k,mask_B(i,j)-1)=-4;
            end
            k=k+1;
        end
    end
end
%%
%求散度,将B补充完全
[A_hxb,A_lxb,~]=find(mask_A==0);
min_Ax=min(A_hxb);
min_Ay=min(A_lxb);
max_Ax=max(A_hxb);
max_Ay=max(A_lxb);
k=1;
for i=min_Ax:max_Ax
    for j=min_Ay:max_Ay
        if i==min_Ax||i==max_Ax||j==min_Ay||j==max_Ay
            k=k+1;
            continue;
        end
        B(k)=image_A(i-1,j)+image_A(i,j-1)+image_A(i,j+1)+image_A(i+1,j)-4*image_A(i,j);%非边界点B为散度
        k=k+1;
    end
end
number=number+1;
end

图像泊松融合 主函数 main.m

%%图像泊松融合
clc,clear
close all
%a是融合的小图像  %b是背景文件
a=double(imread('4.jpg'));
b=double(imread('1.jpg'));


[row_a,col_a,g_a]=size(a);%size()返回矩阵行、列、g_a=3表示rgb,g_a=1表示灰度图
[row_b,col_b,g_b]=size(b);
mask_A=zeros(row_a,col_a);%创建和原图一样大小的零矩阵
imshow(uint8(b));
flat=1;
while flat==1
%法1 鼠标选择位置
    [y_start,x_start]=ginput(1);%获得1个鼠标点击位置

%法2 输入位置数据
%x_start=100;y_start=10;  %输入坐标(10,100)输入顺序Y,X

    x_end=x_start+row_a-1;
    y_end=y_start+col_a-1;
    flat=0;
    if x_end>row_b||y_end>col_b
        disp('Array out of line'); %融合小图像出界,错误提示
        flat=1;
    end
end
mask_B=ones(row_b,col_b);%创建和背景图像一样大小的全1矩阵
mask_B(x_start:x_end,y_start:y_end)=0;%将融入小图像位置部分置0(黑色)
global number  %全局变量
number=1;
%%
[A,B]=create_AB(a(:,:,1),mask_A,b(:,:,1),mask_B); %红色通道
x_R= A\B;
%%
[~,B]=create_AB(a(:,:,2),mask_A,b(:,:,2),mask_B);%绿色通道
x_G= A\B;
%%
[~,B]=create_AB(a(:,:,3),mask_A,b(:,:,3),mask_B);%蓝色通道
x_B= A\B;
%%
[hxb,lxb,l]=find(mask_B==0);%find(A)找到矩阵A非零元素下标,返回行号列号取值
%matlab按列存储
s=[hxb';lxb'];
[s1,id1]=sort(s(1,:)); %对s第一行元素排序
s_z=[s1;s(2,id1)];
hxb=s_z(1,:);
lxb=s_z(2,:);
for i=1:length(l)
    b(hxb(i),lxb(i),1)=x_R(i);
    b(hxb(i),lxb(i),2)=x_G(i);
    b(hxb(i),lxb(i),3)=x_B(i);
end
imshow(uint8(b))

图3 图像泊松融合效果

视频帧直接融合

主函数 main.m

%%此代码意在将小视频融合入原视频
%步骤:
%   1.读取小视频帧、原视频帧
%   2.进行泊松融合
%   3.将融合视频帧组成融合视频
%%
clc
clear
close all;
% addpath(fullfile(pwd, 'picture_ronghe'));
%读取原视频文件
[fastaFile,dirName]=uigetfile({'*.avi;*.mp4;*.rmvb;*.wmv','Video File(*.avi;*.mp4;*.rmvb;*.wmv)';...
    '*.*',  'All Files (*.*)'}, ...
    'Choose a Video File');
[~, name] = fileparts([dirName,fastaFile]);
vid = VideoReader([dirName,fastaFile]);
vid_numFrames = vid.NumFrames;
vid_Frame = read(vid, 1);imshow(vid_Frame),title('第一帧')
%读取放大后的视频
[fastaFile,dirName]=uigetfile({'*.avi;*.mp4;*.rmvb;*.wmv','Video File(*.avi;*.mp4;*.rmvb;*.wmv)';...
    '*.*',  'All Files (*.*)'}, ...
    'Choose a Video File');
[~, name2] = fileparts([dirName,fastaFile]);
vidAmp = VideoReader([dirName,fastaFile]);
vidAmp_numFrames = vidAmp.NumFrames;


outName = fullfile(dirName,[name '_ronghe.avi']);
vidOut = VideoWriter(outName);
vidOut.FrameRate = vid.FrameRate;
open(vidOut)
tic  %tic toc 联合使用,用于计时

%法1 鼠标选择位置
    [y_start,x_start]=ginput(1);%获得1个鼠标点击位置

%法2 输入位置数据
%x_start=100;y_start=10;  %输入坐标(10,100)输入顺序 先Y后X

for i = 1 : min(vid.NumFrames,vidAmp.NumFrames)
% for i = 1 : 20
    Frame = read(vid, i);%原视频帧
    FrameAmp = read(vidAmp, i);%放大视频帧
    integration = main_cc2( Frame, FrameAmp,y_start,x_start);  %输入顺序 Y,X
    writeVideo(vidOut,im2uint8(integration)); 
end
close(vidOut);
toc
fprintf('视频融合完成\n');

调用函数 main_cc2

function I=main_cc2(I,a,y_start,x_start)
close all
a=double(a);
I=double(I);
[row_a,col_a,~]=size(a);%目标文件%放大后的视频帧
[row_b,col_b,~]=size(I);%背景文件%原视频帧
mask_A=zeros(row_a,col_a);
imshow(uint8(I));
    x_end=x_start+row_a-1;
    y_end=y_start+col_a-1;

mask_B=ones(row_b,col_b);
mask_B(x_start:x_end,y_start:y_end)=0;
global number
number=1;
%%
[A,B]=create_AB(a(:,:,1),mask_A,I(:,:,1),mask_B);
x_R= A\B;
%%
[~,B]=create_AB(a(:,:,2),mask_A,I(:,:,2),mask_B);
x_G= A\B;
%%
[~,B]=create_AB(a(:,:,3),mask_A,I(:,:,3),mask_B);
x_B= A\B;
%%
[hxb,lxb,l]=find(mask_B==0);%他是按照一列列进行遍历的
s=[hxb';lxb'];
[s1,id1]=sort(s(1,:));
s_z=[s1;s(2,id1)];
hxb=s_z(1,:);
lxb=s_z(2,:);
for i=1:length(l)
    I(hxb(i),lxb(i),1)=x_R(i);
    I(hxb(i),lxb(i),2)=x_G(i);
    I(hxb(i),lxb(i),3)=x_B(i);
end
% imshow(uint8(I))
I =uint8(I);
end

调用函数 create_AB

function [A,B]=create_AB(image_A,mask_A,image_B,mask_B)
%假设插入的图片为方形
%image_A为插入图片
%mask_A为背景图片的模子,待插入部分为0,不插入部分为1
global number
[hxb,lxb,~]=find(mask_B==0);
B=zeros(length(hxb),1);%创建B
s=[hxb';lxb'];
[s1,id1]=sort(s(1,:));
s_z=[s1;s(2,id1)];%将行下标和列下标的顺序整理为行优先
hxb=s_z(1,:);
lxb=s_z(2,:);
min_x=min(hxb);
min_y=min(lxb);
max_x=max(hxb);
max_y=max(lxb);
k=2;
for i=1:length(hxb)
    mask_B(hxb(i),lxb(i))=k;
    k=k+1;
end
if number==1
A=sparse(zeros(length(hxb),length(hxb)));
end
if number~=1
    A=0;
end
k=1;%k为正在填写A矩阵的第k行
for i=min_x:max_x
    for j=min_y:max_y
        if i==min_x||i==max_x||j==min_y||j==max_y
            if number==1%如果第一次运行该求A函数
                A(k,k)=1;
            end
            B(k)=image_B(i,j);%边界点B为其像素值
            k=k+1;
        end
        if i~=min_x && i~=max_x&&j~=min_y&&j~=max_y
            if number ==1
                A(k,mask_B(i-1,j)-1)=1;
                
                A(k,mask_B(i,j-1)-1)=1;
                
                A(k,mask_B(i,j+1)-1)=1;
                
                A(k,mask_B(i+1,j)-1)=1;
                
                A(k,mask_B(i,j)-1)=-4;
            end
            k=k+1;
        end
    end
end
%%
%求散度,将B补充完全
[A_hxb,A_lxb,~]=find(mask_A==0);
min_Ax=min(A_hxb);
min_Ay=min(A_lxb);
max_Ax=max(A_hxb);
max_Ay=max(A_lxb);
k=1;
for i=min_Ax:max_Ax
    for j=min_Ay:max_Ay
        if i==min_Ax||i==max_Ax||j==min_Ay||j==max_Ay
            k=k+1;
            continue;
        end
        B(k)=image_A(i-1,j)+image_A(i,j-1)+image_A(i,j+1)+image_A(i+1,j)-4*image_A(i,j);%非边界点B为散度
        k=k+1;
    end
end
number=number+1;
end

关于图片直接融合,还有一种方法,用imshow()函数

先显示大图片做背景,再hold on ,在背景图上直接显示小图片,然后保存当前figure

即可

%axes 限制坐标轴范围
xiao=axes('Position',[0.26,0.26,0.35,0.38]);
imshow ('1.jpg');hold on
axes(xiao);
imshow ('4.jpg');
 
 %保存当前figure图像
Frame=getframe;
imwrite(Frame.cdata,'11.jpg');
在这里插入图片描述
方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门