实现功能:
实验目标
- 了解图像颜色空间的转换关系。
- 了解图像的文件结构。
实验内容 - 完成如下颜色空间的转换。(4 Points)
- RGB -> YIQ
- RGB -> HSI
- RGB -> YCbCr
- RGB -> XYZ
选做:
自己实现对 BMP 文件头的读取,并解析 BMP 图像文件。 (2.5 Points)
补充说明
程序从命令行中读取文件路径,并输出 4 个文件,文件名如下:
图像原始文件名-学号-YIQ.bmp
图像原始文件名-学号-HSI.bmp
图像原始文件名-学号-YCbCr.bmp
图像原始文件名-学号-XYZ.bmp
- 了解图像的文件结构。
读取BMP文件头:
效果图:
输出文件:
调用代码demo需要csdn积分下载。
全部文件网址:
https://download.csdn.net/download/qinglingls/10837786
demo单独文件下载网址如下:
https://download.csdn.net/download/qinglingls/10837783
谢谢大家支持。。给我分享资源的动力叭!!!。^ o^
分享了那么多代码,但是我已经穷到没积分了。。
另外附一份实验报告的参考网址:
https://download.csdn.net/download/qinglingls/10837790
function rgb=bmpReader(bmpName) % 自己实现的BMP文件读取函数 % 输入:bmp文件名字 % 输出:rgb格式的矩阵, % 大小:图像高*宽*3 % BITMAPFILEHEADER=14; %根据BMP格式定义BMP文件头大小和头信息文件大小 BITMAPINFOHEADER=40; fid = fopen(bmpName, 'rb');%大端法读取 if fid<=0 fprintf('出现错误,没有这个文件'); return; end %% 按照格式读取bmp文件头 fhead.bfType=fread(fid,2,'bit8'); if fhead.bfType(1)~=66||fhead.bfType(2)~=77 fprintf('Wrong!!It is not a .BMP file!!!!!\n'); return; end fhead.bfSize=fread(fid,1,'uint32'); fhead.bfReserved1=fread(fid,1,'uint16'); fhead.bfReserved2=fread(fid,1,'uint16'); fhead.bfOffBits=fread(fid,1,'uint32'); fprintf('BITMAPFILEHEADER 大小为:%d\n', BITMAPFILEHEADER); fprintf('BITMAPINFOHEADER 大小为:%d\n', BITMAPINFOHEADER); fprintf('%s\t\t-- bfType: 位图文件的类型,必须为\n', fhead.bfType); fprintf('%d\t\t-- bfSize: 位图文件的大小,以字节为单位\n', fhead.bfSize); fprintf('%d\t\t--bfReserved1: 位图文件保留字,必须为0\n', fhead.bfReserved1); fprintf('%d\t\t-- bfReserved2:位图文件保留字,必须为0\n', fhead.bfReserved2); fprintf('%d\t\t-- bfOffBits: 位图数据的起始位置,以相对于位图文件头的偏移量表示,以字节为单位\n', fhead.bfOffBits); %% 按照格式读取bmp头信息大小 %fseek(fid,BITMAPFILEHEADER,'eof');%跳过位图文件头结构BITMAPFILEHEADER寻找结尾 Ihead.biSize=fread(fid,1,'uint32');%读取数据到data里,原始16bit8采样 Ihead.biWidth=fread(fid,1,'uint32'); Ihead.biHeight=fread(fid,1,'uint32'); Ihead.biPlanes=fread(fid,1,'uint16'); Ihead.biBitCount=fread(fid,1,'uint16'); Ihead.biCompression=fread(fid,1,'uint32'); Ihead.biSizeImage=fread(fid,1,'uint32'); Ihead.biXPelsPerMeter=fread(fid,1,'uint32'); Ihead.biYPelsPerMeter=fread(fid,1,'uint32'); Ihead.biClrUsed=fread(fid,1,'uint32'); Ihead.biClrImportant=fread(fid,1,'uint32'); fprintf('%d\t\t-- biSize:本结构所占用字节数\n', Ihead.biSize); fprintf('%d\t\t-- biWidth: 位图的宽度,以像素为单位\n', Ihead.biWidth); fprintf('%d\t\t--biHeight\n: ', Ihead.biHeight); fprintf('%d\t\t--biPlanes\n: ', Ihead.biPlanes); fprintf('%d\t\t--biBitCount: 每个像素所需的位数,必须是1(双色), 4(16色),8(256色)或24(真彩色)之一\n', Ihead.biBitCount); fprintf('%d\t\t-- biCompression: 位图压缩类型,必须是 0(不压缩), 1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一\n', Ihead.biCompression); fprintf('%d\t\t-- biSizeImage: 位图的大小,以字节为单位\n', Ihead.biSizeImage); fprintf('%d\t\t--biXPelsPerMeter: 位图水平分辨率,每米像素数\n', Ihead.biXPelsPerMeter); fprintf('%d\t\t-- biYPelsPerMeter: 位图垂直分辨率,每米像素数\n', Ihead.biYPelsPerMeter); fprintf('%d\t\t--biClrUsed: 位图实际使用的颜色表中的颜色数\n', Ihead.biClrUsed); fprintf('%d\t\t-- biClrImportant: 位图显示过程中重要的颜色数\n', Ihead.biClrImportant); %% % 1,4,8位图像才会使用调色板数据,16,24,32位图像不需要调色板数据,即调色板最多只需要256项(索引0 - 255)。 % 颜色表的大小根据所使用的颜色模式而定:2色图像为8字节;16色图像位64字节;256色图像为1024字节。 % 其中,每4字节表示一种颜色,并以B(蓝色)、G(绿色)、R(红色)、alpha(32位位图的透明度值,一般不需要)。 % 即首先4字节表示颜色号1的颜色,接下来表示颜色号2的颜色,依此类推。 % 颜色表中RGBQUAD结构数据的个数有biBitCount来确定,当biBitCount=1,4,8时,分别有2,16,256个表项。 % 当biBitCount=1时,为2色图像,BMP位图中有2个数据结构RGBQUAD,一个调色板占用4字节数据,所以2色图像的调色板长度为2*4为8字节。 % 当biBitCount=4时,为16色图像,BMP位图中有16个数据结构RGBQUAD,一个调色板占用4字节数据,所以16像的调色板长度为16*4为64字节。 % 当biBitCount=8时,为256色图像,BMP位图中有256个数据结构RGBQUAD,一个调色板占用4字节数据,所以256色图像的调色板长度为256*4为1024字节。 % 当biBitCount=16,24或32时,没有颜色表。 if Ihead.biBitCount==16||Ihead.biBitCount==256 ctTable.rgbBlue=fread(fid,1,'uint8'); ctTable.rgbGreen=fread(fid,1,'uint8'); ctTable.rgbRed=fread(fid,1,'uint8'); ctTable.rgbReserved=fread(fid,1,'uint8'); end %24位图像使用3字节保存颜色值,每一个字节代表一种颜色,按红、绿、蓝排列。 if Ihead.biBitCount==24 %24真彩色图像每点占24位(3字节) buffer=fread(fid,'uint8');%全读取为uint8 %一个扫描行所占的字节数计算方法: dataSizePerLine=(Ihead.biWidth*Ihead.biBitCount)/8; % 一个扫描行所占的字节数 dataSizePerLine= dataSizePerLine/4*4; %字节数必须是4的倍数 %位图数据的大小(不压缩情况下): DataSize= dataSizePerLine* Ihead.biHeight; if DataSize==Ihead.biSizeImage fprintf('DataSize==biSizeImage,成功解析\n'); else fprintf('Wrong,格式错误!!不是24色真彩色图像\n'); end %有填充的直接算作顺序,因为 pitch=mod(Ihead.biWidth,4); if pitch~=0 fprintf('wrong!\n'); return; end %b g r,下面转换为正常顺序 if Ihead.biHeight>0 %height>0 表示图片颠倒, for i=0:1:Ihead.biHeight-1 for j=0:1:Ihead.biWidth-1 %测试图片大小:250*252*3 b=buffer((i*Ihead.biWidth+j)*3+1); g=buffer((i*Ihead.biWidth+j)*3+1+1); r=buffer((i*Ihead.biWidth+j)*3+2+1); rgb(Ihead.biHeight-i,j+1,1)=r; rgb(Ihead.biHeight-i,j+1,2)=g; rgb(Ihead.biHeight-i,j+1,3)=b; % pDC->SetPixel(j,height-i,RGB(r,g,b)); end end end %rgb=cat(3,r,g,b); rgb=uint8(rgb); figure; imshow(rgb);title('自实现函数原图BMP读取显示') elseif Ihead.biBitCount==1 %2彩色图像每点占8位(1字节) buffer=fread(fid,'bit1'); %带调色板的模式,现在不怎么用了,似乎。。所以就不做测试了。。。 %首先4字节表示颜色号1的颜色,接下来表示颜色号2的颜色,依此类推。 for i=0:1:Ihead.biHeight-1 for j=0:1:Ihead.biWidth-1 b=buffer((i*Ihead.biWidth+j)*4+1); g=buffer((i*Ihead.biWidth+j)*4+1+1); r=buffer((i*Ihead.biWidth+j)*4+2+1); rgb(Ihead.biHeight-i,j+1,1)=r; rgb(Ihead.biHeight-i,j+1,2)=g; rgb(Ihead.biHeight-i,j+1,3)=b; end end rgb=uint8(rgb); figure imshow(rgb); title('自实现函数原图BMP读取显示') end end
%hsi2rgb function hsi = rgb2hsi(rgb) % 实现从RGB到HSI的转换 % 输入:rgb向量矩阵 % 输出:hsi向量矩阵 rgb = im2double(rgb); r = rgb(:, :, 1); g = rgb(:, :, 2); b = rgb(:, :, 3); % Implement the conversion equations. num = 0.5*((r - g) + (r - b)); den = sqrt((r - g).^2 + (r - b).*(g - b)); theta = acos(num./(den + eps)); H = theta; H(b > g) = 2*pi - H(b > g); H = H/(2*pi); num = min(min(r, g), b); den = r + g + b; den(den == 0) = eps; S = 1 - 3.* num./den; H(S == 0) = 0; I = (r + g + b)/3; % Combine all three results into an hsi image. hsi = cat(3, H, S, I); %HSI2RGB function rgb = hsi2rgb(hsi) % Extract the individual HSI component images. H = hsi(:, :, 1) * 2 * pi; S = hsi(:, :, 2); I = hsi(:, :, 3); % Implement the conversion equations. R = zeros(size(hsi, 1), size(hsi, 2)); G = zeros(size(hsi, 1), size(hsi, 2)); B = zeros(size(hsi, 1), size(hsi, 2)); % RG sector (0 <= H < 2*pi/3). idx = find( (0 <= H) & (H < 2*pi/3)); B(idx) = I(idx) .* (1 - S(idx)); R(idx) = I(idx) .* (1 + S(idx) .* cos(H(idx)) ./ ... cos(pi/3 - H(idx))); G(idx) = 3*I(idx) - (R(idx) + B(idx)); % BG sector (2*pi/3 <= H < 4*pi/3). idx = find( (2*pi/3 <= H) & (H < 4*pi/3) ); R(idx) = I(idx) .* (1 - S(idx)); G(idx) = I(idx) .* (1 + S(idx) .* cos(H(idx) - 2*pi/3) ./ ... cos(pi - H(idx))); B(idx) = 3*I(idx) - (R(idx) + G(idx)); % BR sector. idx = find( (4*pi/3 <= H) & (H <= 2*pi)); G(idx) = I(idx) .* (1 - S(idx)); B(idx) = I(idx) .* (1 + S(idx) .* cos(H(idx) - 4*pi/3) ./ ... cos(5*pi/3 - H(idx))); R(idx) = 3*I(idx) - (G(idx) + B(idx)); rgb = cat(3, R, G, B); rgb = max(min(rgb, 1), 0);
rgb2XYZ.m文件
function rgb2XYZ(filename) % RGB到XYZ的转换 % 输入:文件名 % 无输出,直接打印图像并写入文件 % rgb = imread(filename); subplot(2,3,1),imshow(rgb,'InitialMagnification','fit');title('原图像'); rgb =double(rgb);%双精度化(0-255) x = 0.*rgb(:,:,1)+0.*rgb(:,:,2)+0.*rgb(:,:,3); x = mat2gray(x);%把矩阵转化为灰度图像 y = 0.*rgb(:,:,1)+0.*rgb(:,:,2)+0.072169*rgb(:,:,3); y = mat2gray(y); z = 0.019334*rgb(:,:,1)+0.*rgb(:,:,2)+0.*rgb(:,:,3); z = mat2gray(z); xyz = cat(3,x,y,z);%把x,y,z连在一起 subplot(2,3,3),imshow(xyz);title('XYZ图像'); subplot(2,3,4),imshow(x);title('X图像'); subplot(2,3,5),imshow(y);title('Y图像'); subplot(2,3,6),imshow(z);title('Z图像'); imwrite(xyz,strcat(filename,'--XYZ.bmp')); end
rgb2YCbCr.m
function rgb2YCbCr(filename) % % RGB到YCbCr的转换 % 输入:文件名 % 无输出,直接打印图像并写入文件 % ima = imread(filename); %读取一张名为abc.bmp的图片 ima_ycbcr = rgb2ycbcr(ima);%将rgb格式转为ycbcr格式 subplot(2,3,1); imshow(ima_ycbcr(:,:,1)); title('Y'); subplot(2,3,2); imshow(ima_ycbcr(:,:,2)); title('Cb') subplot(2,3,3); imshow(ima_ycbcr(:,:,3)); title('Cr') subplot(2,3,4); x = cat(3, ima_ycbcr(:,:,1), ima_ycbcr(:,:,2), ima_ycbcr(:,:,3)); imshow(x); title('ima_ycbcr') subplot(2,3,5); imshow(ima); title('原图'); imwrite(ima,strcat(filename,'--YCbCr.bmp')); end
rgb2yiq_func.m
% rgb=imread(fileName); RGB=(rgb); r=RGB(:,:,1); g=RGB(:,:,2); b=RGB(:,:,3); Y=0.299*r+0.587*g+0.114*b; I=0.596*r-0.274*g-0.322*b; Q=0.211*r-0.523*g+0.312*b; figure subplot(2,3,1); imshow(Y); title('YRGB'); subplot(2,3,2); imshow(I); title('IRGB') subplot(2,3,3); imshow(Q); title('QRGB') subplot(2,3,4); imshow(RGB); title('RGB') subplot(2,3,5); img_YIQ=cat(3,Y,I,Q); imwrite(img_YIQ,strcat(fileName,'--YIQ.bmp')); imshow(img_YIQ); title('RGB2YIQ图像'); end
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/233241.html原文链接:https://javaforall.net