2月24日 CVST工具箱模块仿真与图像处理(二)、基于Vision对象的边缘检测、余弦变换压缩,与峰值信噪比

课程作业1:边缘检测

videoFReader = vision.VideoFileReader('test.mp4','ImageColorSpace','Intensity'); 
videoPlayer = vision.VideoPlayer('Name','EdgesCanny'); 
videoPlayer1 = vision.VideoPlayer('Name','EdgesSobel'); 
% 读入视频图像并显示 
WindowSize=[190,300];

while ~isDone(videoFReader)   
    frame = step(videoFReader);   
    %step(videoPlayer,frame); 
    Edge = edge(frame,'canny');%detection edge
    BW = edge(frame,'prewitt');
    step(videoPlayer,Edge);%show edge
    step(videoPlayer1,Edge);%show edge
end

在这里插入图片描述

在这里插入图片描述

项目2:余弦变换压缩,与峰值信噪比

Matlab图像处理函数blkproc的解释

https://blog.csdn.net/wangkun1340378/article/details/78682909

功能:对图像进行分块处理
函数调用形式:B = blkproc(A,[m n],fun, parameter1, parameter2, …)
B = blkproc(A,[m n],[mborder nborder],fun,…)
B = blkproc(A,‘indexed’,…)
参数解释:[m n] :图像以mn为分块单位,对图像进行处理(如8像素8像素)
Fun: 应用此函数对分别对每个mn分块的像素进行处理
parameter1, parameter2: 要传给fun函数的参数
mborder nborder:对每个m
n块上下进行mborder个单位的扩充,左右进行nborder个单位的扩充,扩充的像素值为0,fun函数对整个扩充后的分块进行处理。

例子:1 图像压缩

I = imread('cameraman.tif'); 
I=im2double(I);  
T=dctmtx(8);%生成一个8*8 DCT变换矩阵
B=blkproc(I,[8,8],'P1*x*P2',T,T');% x就是每一个分成的8*8大小的块,P1*x*P2相当于像素块的处理函数,p1=T p2=T’,也就是fun=p1*x*p2'=T*x*T'的功能是进行离散余弦变换
  mask = [1   1   1   1   0   0   0   0
          1   1   1   0   0   0   0   0
          1   1   0   0   0   0   0   0
          1   0   0   0   0   0   0   0
          0   0   0   0   0   0   0   0
          0   0   0   0   0   0   0   0
          0   0   0   0   0   0   0   0
          0   0   0   0   0   0   0   0];
%保留左上角十个系数
B2 = blkproc(B,[8 8],'P1.*x',mask); %舍弃每个块中的高频系数,达到图像压缩的目的
I2=blkproc(B2,[8,8],'P1*x*P2',T,T');  %进行反余弦变换,得到压缩后的图象
imshow(I);   
figure;                            
imshow(I2);      
%注意:如果是三维图象(如RGB)则要先将图像转换成图像变成灰度图象或者用reshape函数转换维数。

matlab 计算图像的峰值信噪比PSNR以及均方根误差MSE

PSNR 是最普遍,最广泛使用的评鉴画质的客观量测法,不过许多实验结果都显示,PSNR 的分数无法和人眼看到的视觉品质完全一致,有可能 PSNR 较高者看起来反而比PSNR 较低者差。
这是因为人眼的视觉对于误差的敏感度并不是绝对的,其感知结果会受到许多因素的影响而产生变化(例如:人眼对空间频率较低的对比差异敏感度较高,人眼对亮度对比差异的敏感度较色度高,人眼对一个区域的感知结果会受到其周围邻近区域的影响)。
(参考百度百科)
在这里插入图片描述
PSNR,峰值信噪比,通常用来评价一幅图像压缩后和原图像相比质量的好坏,当然,压缩后图像一定会比原图像质量差的,所以就用这样一个评价指标来规定标准了。PSNR越高,压缩后失真越小。这里主要定义了两个值,一个是均方差MSE,另一个是峰值信噪比PSNR。

这里的MAX通常是图像的灰度级,一般就是255了。应该转换成uint进行求解峰值信噪比PSNR。

https://blog.csdn.net/sac761/article/details/76547615

% 这个部分采用的8位浮点型。
img=double(img);
imgn=double(imgn);
 
B=8;                %编码一个像素用多少二进制位
MAX=2^B-1;          %图像有多少灰度级
MES=sum(sum((img-imgn).^2))/(h*w);     %均方差
PSNR=20*log10(MAX/sqrt(MES));           %峰值信噪比

当PSNR值大于30dB的时候,可以认为去噪或压缩后的图像质量较好,低于20dB表示图像质量不可接受

写成function:(默认是用的uint,这里的MAX通常是图像的灰度级,一般就是255了。应该转换成uint进行求解峰值信噪比PSNR。)

%%%%%%%%%%%%function
function [PSNR, MSE] = psnr(X, Y)
% 计算峰值信噪比PSNR、均方根误差MSE
% 如果输入Y为空,则视为X与其本身来计算PSNR、MSE

if nargin<2
    D = X;
else
    if any(size(X)~=size(Y))
        error('The input size is not equal to each other!');
    end
    D = X-Y;
end
MSE = sum(D(:).*D(:))/prod(size(X));
PSNR = 10*log10(255^2/MSE);
display(MSE);
display(PSNR);

%%%%%%%%%%%%%%%%%%%%%主函数
function main()
clc; close all;
I = imread('rice.png');
I1 = imnoise(I, 'salt & pepper');
figure; 
subplot(1, 2, 1); imshow(I); title('原图像');
subplot(1, 2, 2); imshow(I1); title('加噪声图像');
[PSNR, MSE] = psnr(I, I1);

信噪比

以高斯噪声为例:

若有用信号 s ( n ) s(n) 的最大幅度 a m am ,要求得到的信噪比为 p p ,则 p = 10 l o g 10 [ ( a m 2 ) / b 2 ] p=10log_{10}[(am^2)/b^2] ,用这个公式反推出高斯噪声的方差 b 2 b^2 ,若s(n)单通道实信号,则Matlab程序就是 x = s + b r a n d n ( s i z e ( s ) ) x=s+b*randn(size(s)) ;若s(n)是正交双通道信号,则Matlab程序就是 x = s + b / s q r t ( 2 ) r a n d n ( s i z e ( s ) ) x=s+b/sqrt(2)*randn(size(s))

如果s(n)是一个N行、2列的复信号,前后两列各表示实部和虚部,则b/sqrt(2)randn(size(s))产生的也是N×2的高斯分布噪声,实部和虚部的方差均为b/sqrt(2)。实部和虚部分别产生也可以,但不能用brandn(size(s))。第一,如果这样产生噪声,那么最终信号的信噪比应该用 p = 10 l o g 10 [ ( a m 2 ) / ( 2 b 2 ) ] p=10log_{10}[(am^2)/(2*b^2)] ;第二,不能用size(s),应该用size©,c为s(n)的实(虚)部列矢量的长度。

Matlab中计算信噪比方式:

function snr=SNR(I,In)
% 计算信号噪声比函数
% I :original signal
% In:noisy signal(ie. Original signal + noise signal)
% snr=10*log10(sigma2(I2)/sigma2(I2-I1))

[row,col,nchannel]=size(I);

snr=0;
if nchannel==1%gray image
	Ps=sum(sum((I-mean(mean(I))).^2));%signal power
	Pn=sum(sum((I-In).^2));%noise power
	snr=10*log10(Ps/Pn);
	
elseif nchannel==3%color image
	for i=1:3
		Ps=sum(sum((I(:,:,i)-mean(mean(I(:,:,i)))).^2));%signal power
		Pn=sum(sum((I(:,:,i)-In(:,:,i)).^2));%noise power
		snr=snr+10*log10(Ps/Pn);
	end
	snr=snr/3;
	
end
%========================================

向已知信号添加噪声

说起“向已知信号添加噪声”,介绍的两个常用函数,
http://blog.sina.com.cn/s/blog_758ebadc0100qchy.html

MATLAB中产生高斯白噪声非常方便,可以直接应用两个函数,一个是WGN,另一个是AWGN。WGN用于产生高斯白噪声AWGN则用于在某一信号中加入高斯白噪声

  1. WGN:产生高斯白噪声
    y = wgn(m,n,p) 产生一个m行n列的高斯白噪声的矩阵,p以dBW为单位指定输出噪声的强度。
    y = wgn(m,n,p,imp) 以欧姆(Ohm)为单位指定负载阻抗。
    y = wgn(m,n,p,imp,state) 重置RANDN的状态。

在数值变量后还可附加一些标志性参数:

y = wgn(…,POWERTYPE) 指定p的单位。POWERTYPE可以是’dBW’,‘dBm’或’linear’。线性强度(linear power)以瓦特(Watt)为单位。
y = wgn(…,OUTPUTTYPE) 指定输出类型。OUTPUTTYPE可以是’real’或’complex’。

  1. AWGN:在某一信号中加入高斯白噪声
    y = awgn(x,SNR) 在信号x中加入高斯白噪声。信噪比SNR以dB为单位。x的强度假定为0dBW。如果x是复数,就加入复噪声。
    y = awgn(x,SNR,SIGPOWER) 如果SIGPOWER是数值,则其代表以dBW为单位的信号强度;如果SIGPOWER为’measured’,则函数将在加入噪声之前测定信号强度。
    y = awgn(x,SNR,SIGPOWER,STATE) 重置RANDN的状态。
    y = awgn(…,POWERTYPE) 指定SNR和SIGPOWER的单位。POWERTYPE可以是’dB’或’linear’。如果POWERTYPE是’dB’,那么SNR以dB为单位,而SIGPOWER以dBW为单位。如果POWERTYPE是’linear’,那么SNR作为比值来度量,而SIGPOWER以瓦特为单位。

注释

  1. 分贝(decibel, dB):分贝(dB)是表示相对功率或幅度电平的标准单位,换句话说,就是我们用来表示两个能量之间的差别的一种表示单位,它不是一个绝对单位。例如,电子系统中将电压、电流、功率等物理量的强弱通称为电平,电平的单位通常就以分贝表示,即事先取一个电压或电流作为参考值(0dB),用待表示的量与参考值之比取对数,再乘以20作为电平的分贝数(功率的电平值改乘10)。
  2. 分贝瓦(dBW, dB Watt):指以1W的输出功率为基准时,用分贝来测量的功率放大器的功率值。
  3. dBm (dB-milliWatt):即与1milliWatt(毫瓦)作比较得出的数字。
    0 dBm = 1 mW
    10 dBm = 10 mW
    20 dBm = 100 mW

randn函数产生高斯分布序列

也可直接用randn函数产生高斯分布序列,例如:

y=randn(1,2500);
y=y/std(y);
y=y-mean(y);
a=0.0128;
b=sqrt(0.9596);
y=a+b*y;

就得到了 N ( 0.0128, 0.9596 ) 的高斯分布序列

产生指定方差和均值的随机数

设某个随机变量 x x 均值为 m u mu ,方差为 v a r 2 var^2 ,若要产生同样分布的随机变量 y y ,但使新的随机变量参数改变,均值为 m u 1 mu_1 ,方差为 v a r 1 2 var_1^2 ,可以用如下公式进行变换:

y = v a r 1 / v a r ( x m u ) + m u 1 y=var_1/var*(x-mu)+mu_1 ,其中 x x 为随机变量,其余为常数(原分布参数)。

具体到正态分布,若要产生均值为 u u ,方差为 o 2 o^2 M N M*N 的随机数矩阵,可以用
y = o r a n d n ( M , N ) + u y=o*randn(M,N)+u 得到。
对于均匀分布,若要产生 [ a , b ] [a,b] 区间的均匀分布的 M N M*N 的随机数矩阵,则可以用
y = r a n d ( M , N ) ( b a ) + a y=rand(M,N)*(b-a)+a 得到。

rand 与randn

%===========================================================%
1)        rand产生的是[0,1]上的均匀分布的随机序列
2)        randn产生均值为0,方差为1的高斯随机序列,也就是白噪声序列;
%===================================================================%

也就是说,可以直接使用上面两个函数对原始信号添加噪声(例如y=x+rand(length(x),1)或者y=x+randn(length(x),1))

项目代码

%%灰度处理
close all;
clear all;
Img=imread('t2.png');
[n m a]=size(Img);%判断图像的大小
GrayImage= rgb2gray(Img);%调用MATLAB函数实现灰度化
I =  im2double(GrayImage);
D = dct2(I);          %DCT变换
D1 = idct2(D);        %逆变换
subplot(2,2,1);imshow(I);
subplot(2,2,2);imshow(im2uint8(D));
subplot(2,2,3);imshow(im2uint8(D1));
subplot(2,2,4);imshow(log(abs(D)),[]);
colormap(gray(8));colorbar;

在这里插入图片描述

%%灰度处理
close all;
clear all;
Img=imread('t2.png');
[n m a]=size(Img);%判断图像的大小

GrayImage= rgb2gray(Img);%调用MATLAB函数实现灰度化
I =  im2double(GrayImage);
D = dctmtx(8);
C = blkproc(I,[8,8],'P1*x*P2',D,D');  %D'为D的转置
%subplot(1,1,1);imshow(im2uint8(C));
%subplot(1,1,1);imshow(log(abs(C)),[]);
%colormap(gray(8));colorbar;
% mask1=[1 1 1 1 1 0 0 0%保留全部15个系数
% 1 1 1 1 0 0 0 0
% 1 1 1 0 0 0 0 0
% 1 1 0 0 0 0 0 0
% 1 0 0 0 0 0 0 0
% 0 0 0 0 0 0 0 0
% 0 0 0 0 0 0 0 0
% 0 0 0 0 0 0 0 0];
mask1=ones(8);%保留全部64个系数
mask2=[1 1 1 1 0 0 0 0
1 1 1 0 0 0 0 0
1 1 0 0 0 0 0 0
1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0];
mask3=[1 1 0 0 0 0 0 0
1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0];

X = blkproc(C,[8,8],'P1.*x',mask1);  %保留全部64个系数
I1  = blkproc(X,[8,8],'P1*x*P2',D',D);    %重构图像
X2 = blkproc(C,[8,8],'P1.*x',mask2);  %保留10个系数
I2  = blkproc(X2,[8,8],'P1*x*P2',D',D);    %重构图像
X3 = blkproc(C,[8,8],'P1.*x',mask3);   %保留3个系数
I3  = blkproc(X3,[8,8],'P1*x*P2',D',D);    %重构图像
subplot(2,4,1);imshow(I);
subplot(2,4,2);imshow(I1);
subplot(2,4,3);imshow(I2);
subplot(2,4,4);imshow(I3);
[PSNR, MSE]=psnr(im2uint8(I),im2uint8(I1))

在这里插入图片描述
在这里插入图片描述

C/C++代码的自动生成

基于MATLAB Coder将matlab代码转换成C代码 https://blog.csdn.net/zyqdragon/article/details/71512790
在这里插入图片描述
在这里插入图片描述
function要有输入量与输出量。然后写%#codegen 表示该function会生成c/c++代码。
编译指令 %#codegen
将 %#codegen 指令(或编译指令)添加到函数中的函数签名之后,以指示您要为 MATLAB® 算法生成代码。添加此指令将指示 MATLAB 代码分析器帮助您诊断并修复在代码生成过程中会导致错误的违规情况。参考:https://ww2.mathworks.cn/help/simulink/ug/adding-the-compilation-directive-codegen.html
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

注意:

在这里插入图片描述
输入类型doubule(1x1)变成数组doubule(5x5),会改变输出的情况。
在这里插入图片描述

调用代码

多分辨率金字塔化
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

发布了66 篇原创文章 · 获赞 3 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/djfjkj52/article/details/104439848
今日推荐