彩色图像处理
实验七 彩色图像处理
一、实验目的
- 掌握彩色图像处理的概念及其计算方法;
- 熟练使用matlab实现图像的傅里叶变换;
二、实验环境
- PC计算机
- MatLab软件/语言包括图像处理工具箱(Image Processing Toolbox)
- 实验所需要的图片
- 实验原理
自己写彩色图像处理的原理和流程!
1、通过RGB生成简单彩色图像
通过给R、G、B三个分量赋值,利用三基色原理生成简单的彩色图像,每个分量单独生成的图像都是灰度图像,只有三个分量叠加才能变成彩色图像,比如利用cat()函数。
- RGB空间转换为HIS空间
- 彩色分割
彩色图像分割就是利用图像的彩色信息,将图像分割为一些感兴趣区域的图像处理方法。彩色图像的分割可以看作是灰度图像分割向彩色空间的一种扩展和延伸。在彩色图像的分割中需要依据不同的分割要求选择不同的彩色模型和分割方法
4、边缘检测
边缘检测的实质是采用某种算法来提取出图像中对象与背景间的交界线。我们将边缘定义为图像中灰度发生急剧变化的区域边界。图像灰度的变化情况可以用图像灰度分布的梯度来反映,因此我们可以用局部图像微分技术来获得边缘检测算子。经典的边缘检测方法,是通过对原始图像中像素的某小邻域构造边缘检测算子来达到检测边缘这一目的的。
全彩色图像处理处理方法分为两大类:
分别处理每一幅图像的分量,然后由分别处理过的分量图像形成一幅处理过的合成彩色图像。对每个分量的处理技术可以应用到对灰度图像处理的技术上,但这种通道式的独立处理技术忽略了通道间的相互影响。
直接处理彩色像素(向量)。全彩色图像至少有3个分量,所以彩色像素实际上是向量。
如,在RGB系统中。令c表示RGB彩色空间中的一个任意向量:
c的分量仅是一幅彩色图像在一点处的RGB分量。
彩色分量是坐标(x,y)的函数,表示为:
对大小为M*N的图像,有MN个这样的向量c(x,y)。
为了使每种彩色分量的处理和基于向量的处理达到同样的效果,需要满足以下两个条件:
处理必须对向量和标量都可用;
对向量的每个分量的操作对于其他分量必须是独立的。
四、实验图像
- 实验步骤和结果
提示:
- 实现彩色图像的缩放、旋转
代码如下:
clear;
img=imread('E:\ins风\huahai.tif'); %读入原图像
B=size(img);%获取图像的高度和宽度
K1 =str2double(inputdlg('请输入列缩放倍数', 'INPUT scale factor', 1, {'0.5'}));%行默认变为原来的0.5倍
K2 =str2double(inputdlg('请输入行缩放倍数', 'INPUT scale factor', 1, {'0.5'}));%列默认变为原来的0.5倍
width = K1 * B(1); %缩放后的图像宽度
height = K2 * B(2); %缩放后的图像高度
for p=1:3
imgn(:,:,p) = uint8(zeros(round(width),round(height))); %创建输出图像矩阵,round是进行数值取整
end
widthScale = B(1)/width; %列缩放倍数的倒数
heightScale = B(2)/height;%行缩放倍数的倒数
for q=1:3
for x = 5:width - 5 % 5是为了防止矩阵超出边界溢出
for y = 5:height - 5
oldX = x * widthScale; % oldX,oldY为原坐标,x,y为新坐标
oldY = y * heightScale;
if(oldX/double(uint16(oldX)) == 1.0) && (oldY/double(uint16(oldY)) == 1.0) %判断oldx,oldy是否为整数
imgn(x,y,q) = img(int16(oldX),int16(oldY),q);
else
a = double(round(oldX));
b = double(round(oldY)); %若不是整数四舍五入后把临近值赋过去
imgn(x,y,q) = img(a,b,q);
end
end
end
end
[W, H, G] = size(img); % 获取图像大小
img_r=img(:,:,1);
img_g=img(:,:,2);
img_b=img(:,:,3);%获取图像的RGB值
X = 20; % 偏移角度,角度可以自己换
Y = pi/180*X; %偏转弧度,由于matlab里面的三角函数的参数是弧度,需进行角度转弧度处理
tras = [cos(Y) -sin(Y) 0; sin(Y) cos(Y) 0; 0 0 1]; % 平移的变换矩阵
res = zeros(W, H, 3); % 构造结果矩阵。每个像素点默认初始化为0(黑色)
for i = 1 : W
for j = 1 : H
temp = [i; j; 1];
temp = tras * temp; % 矩阵乘法
x = round(uint16(temp(1, 1)));
y = round(uint16(temp(2, 1)));%x、y分别为通过矩阵乘法得到后的平移位置的横纵坐标值
% 变换后的位置判断是否越界
if (x <= W) && (y <= H)&&(x >= 1) && (y >= 1)
res(x,y,1) = img_r(i, j);
res(x,y,2) = img_g(i, j);
res(x,y,3) = img_b(i, j);%将新的RGB值赋予在背景上
end
end
end
%插值处理,由于算法问题(小数取整),旋转后并不是每一个像素点都有值,因此需要在没有值的像素点再填充像素点
for a =2 : (W - 1)
for b=2 :( H - 1)
for c=1 : 3
if res(a,b,c)==0&&res(a,b-1,c)~=0&&res(a,b+1,c)~=0
res(a,b,c)=res(a,b-1,c);
end
end
end
end
subplot(1,3,1)
imshow(img);
title('原图20101110227');
subplot(1,3,2)
imshow(imgn);
title('最邻近插值缩放');
subplot(1,3,3)
imshow(uint8(res));
title('20°旋转');
结果如下:
- 实现彩色图像的对数运算(用两种方式,直接对RGB模型运算和分别对三个通道运算再合成)
代码如下:
f = imread('E:\ins风\huahai.tif');
G=mat2gray(log(1+double(f)));
% matlab中数值一般采用double型(64位)存储和运算。mat2gray对图像灰度进行归一化处理
subplot(1,3,1);
imshow(f);
xlabel(' a). 原始图像20101110227');
subplot(1,3,2);
imshow(G,[]); % 自动调整数据的范围以便于显示
xlabel(' b). 对数变换1');
v=10;
r=mat2gray(double(f));
S=log(1+v*r)/(log(v+1));
subplot(1,3,3);
imshow(S,[]);
xlabel('b). 对数变换2');
结果如下:
- 实现彩色图像的幂律运算
代码如下:
% 1. 实现幂律变换(幂次变换)
imgrgb = imread('E:\ins风\huahai.tif');
imggray = rgb2gray(imgrgb); %将rgb图像转换成灰度图像
figure('Name', '对比gamma数值实现幂律变换'); %设置标题
subplot(221);
imshow(imggray);%显示灰度图像
title('原始灰度图像20101110227');
I = imadjust(imggray,[0 1],[0 1],0.3);%grammer值为0.3
subplot(222);
imshow(I);
title('gamma值为0.3灰度图像');
J = imadjust(imggray,[0 1],[0 1],0.8);%grammer值为0.8
subplot(223);
imshow(J);
title('gamma值为0.8灰度图像');
K = imadjust(imggray,[0 1],[0 1],1.7);%grammer值为1.7
subplot(224);
imshow(K);
title('gamma值为1.7灰度图像');
结果如下:
- 实现彩色图像的均值滤波(整体运算和分别运算,并比较两者的差别)
代码如下:
input = imread('E:\ins风\huahai.tif');
mask = 1 / 16 * [1 2 1; 2 4 2; 1 2 1]; % 考虑3*3的滤波模板
% 使用库函数实现(在对sobel求取边缘的时候貌似也得分别求水平和垂直边缘)
output1 = imfilter(double(input), mask, 'conv', 0, 'full'); %求竖边缘
% 下面自己实现
[m, n] = size(input);
% 先填充输入图像,这里依旧通过0来填充外边界
input_temp = zeros(m + 4, n + 4);
% 初始化输入图像
input_temp(3: m + 3 - 1, 3: n + 3 - 1) = input;
% 让模板滑过扩展的输入向量
xx = size(input_temp, 1) - 3 + 1;
yy = size(input_temp, 2) - 3 + 1;
output = zeros(xx,yy);
for i = 1: xx
for j = 1: yy
output(i, j) = sum( sum( input_temp(i: i + 3 - 1 , j : j + 3 - 1) .* mask ) ) ;
end
end
fprintf('调用库函数imfilter完成相关运算');
subplot(131);imshow( uint8(input) ); title('原图20101110227');
subplot(132);imshow( uint8(output1) );title('整体运算实现均值滤波');
subplot(133);imshow( uint8(output) ); title('分别运算实现均值滤波');
结果如下:
- 实现彩色图像的中值滤波
注意:将每一步的函数执行语句和实验结果写入实验报告,显示的结果图片请命名,且命名里面包含自己的学号!
代码:
clear all;
clc;
I=imread('E:\ins风\huahai.tif');
OutImg=I;
R=I(:,:,1);
G=I(:,:,2);
B=I(:,:,3);
R=medfilt2(R,[3,3]);
G=medfilt2(G,[3,3]);
B=medfilt2(B,[3,3]);
I1=cat(3,R,G,B); % 对彩色图像R,G,B三个通道分别进行3×3模板的中值滤波 cat函数用于连接两个矩阵或数组
R=filter2(fspecial('average',3),R)/255;
G=filter2(fspecial('average',3),G)/255;
B=filter2(fspecial('average',3),B)/255;
subplot(1,3,1);
imshow(I);
title('原图201011102227')
subplot(1,3,2);
imshow(I1);
title('中值滤波')
运行结果:
六、实验思考
附加题:分别在RGB和HIS彩色空间实现对彩色图像的直方图均衡化,并进行对比。
代码:
%coding = UTF8
%测试直方图均衡化的方法
%2020-10-23
%version1.0
%by neverland!
%读取图像
im = imread('E:\ins风\huahai.tif');
%在rgb通道作直方图均衡化
r = im(:,:,1);
g = im(:,:,2);
b = im(:,:,3);
r_ = histeq(r);
g_ = histeq(g);
b_ = histeq(b);
im_ = cat(3,r_,g_,b_);
%在hsi通道作直方图均衡化
im1 = rgb2hsv(im);
H = im1(:,:,1);
S = im1(:,:,2);
I = im1(:,:,3);
%复制变量
I_ = I;
I_2 = I;
S_ = S;
%对S变量进行处理
index3 = (S<1 & S>0);
S_(index3) = 6*S(index3) - S(index3).^2;
%利用MATLAB自带的直方图均衡化
I_ = adapthisteq(I);
I_1 = histeq(I);
%利用pitas的理论
index1 = I<0.5;
index2 = I>0.5;
I_2(index1) = 12*I(index1).^2;
I_2(index2) = 12*(1-I(index2)).^2;
%第一幅图histeq
im1_ = cat(3,H,S,I_);
im1_ = hsv2rgb(im1_);
%第二幅图用的是adathisteq
im2 = cat(3,H,S,I_1);
im2_ = hsv2rgb(im2);
%第三幅图用1996年的理论
im3 = cat(3,H,S,I_2);
im3_ = hsv2rgb(im3);
%再处理一次;
im4 = cat(3,H,S_,I_2);
im4_ = hsv2rgb(im4);
%分开显示下
subplot(2,3,1);imshow(im);title('原始图像20101110227','FontSize',20);
subplot(2,3,2);imshow(im_);title('RGB空间内作直方图均衡化','fontsize',20);
subplot(2,3,3);imshow(im1_);title('HSI空间内作直方图均衡化','fontsize',20);
subplot(2,3,4);imshow(im2_);title('HSI空间内作直方图均衡化','fontsize',20);
subplot(2,3,5);imshow(im3_);title('HSI空间内作直方图均衡化','fontsize',20);
subplot(2,3,6);imshow(im4_);title('HSI空间内作直方图均衡化','fontsize',20);
运行结果: