2025年3月24日 星期一 甲辰(龙)年 月廿三 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > Python

关于图像融合 视频融合

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

图像融合 视频融合

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

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

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

直接融合

图像直接融合

  • %%图像直接融合
  • 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');
在这里插入图片描述
方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门