VC++图形图像处理源代码

合集下载

数字图像处理及matlab实现源代码【1】

数字图像处理及matlab实现源代码【1】

% *-*--*-*-*-*-*-*-*-*-*-*-*图像处理*-*-*-*-*-*-*-*-*-*-*-*%{% (一)图像文件的读/写A=imread('drum.jpg'); % 读入图像imshow(A); % 显示图像imwrite(A,'drum.jpg');info=imfinfo('drum.jpg') % 查询图像文件信息% 用colorbar函数将颜色条添加到坐标轴对象中RGB=imread('drum.jpg');I=rgb2gray(RGB); % 把RGB图像转换成灰度图像h=[1 2 1;0 0 0;-1 -2 -1];I2=filter2(h,I);imshow(I2,[]);colorbar('vert') % 将颜色条添加到坐标轴对象中% wrap函数将图像作为纹理进行映射A=imread('4.jpg');imshow(A);I=rgb2gray(RGB);[x,y,z]=sphere;warp(x,y,z,I); % 用warp函数将图像作为纹理进行映射%}% subimage函数实现一个图形窗口中显示多幅图像RGB=imread('drum.jpg');I=rgb2gray(RGB);subplot(1,2,1);subimage(RGB); % subimage函数实现一个图形窗口中显示多幅图像subplot(1,2,2),subimage(I);% *-*--*-*-*-*-*-*-*-*-*-*-*图像处理*-*-*-*-*-*-*-*-*-*-*-*% (二)图像处理的基本操作% ----------------图像代数运算------------------%{% imadd函数实现两幅图像的相加或给一幅图像加上一个常数% 给图像每个像素都增加亮度I=imread('4.jpg');J=imadd(I,100); % 给图像增加亮度subplot(1,2,1),imshow(I);title('原图');subplot(1,2,2),imshow(J);title('增加亮度图');%% imsubtract函数实现将一幅图像从另一个图像中减去或减去一个常数I=imread('drum.jpg');J=imsubtract(I,100); % 给图像减去亮度subplot(1,2,1),imshow(I);%% immultiply实现两幅图像的相乘或者一幅图像的亮度缩放I=imread('drum.jpg');J=immultiply(I,2); % 进行亮度缩放subplot(1,2,1),imshow(I);subplot(1,2,2),imshow(J);%% imdivide函数实现两幅图像的除法或一幅图像的亮度缩放I=imread('4.jpg');J=imdivide(I,0.5); % 图像的亮度缩放subplot(1,2,1),imshow(I);subplot(1,2,2),imshow(J);%}% ----------------图像的空间域操作------------------%{% imresize函数实现图像的缩放J=imread('4.jpg');subplot(1,2,1),imshow(J);title('原图');X1=imresize(J,0.2); % 对图像进行缩放subplot(1,2,2),imshow(X1);title('缩放图');%% imrotate函数实现图像的旋转I=imread('drum.jpg');J=imrotate(I,50,'bilinear'); % 对图像进行旋转subplot(1,2,1),imshow(I);subplot(1,2,2),imshow(J);%% imcrop函数实现图像的剪切I=imread('drum.jpg');I2=imcrop(I,[1 100 130 112]); % 对图像进行剪切subplot(1,2,1),imshow(I);subplot(1,2,2),imshow(I2);%}% ----------------特定区域处理------------------%{% roipoly函数用于选择图像中的多边形区域I=imread('4.jpg');c=[200 250 278 248 199 172];r=[21 21 75 121 121 75];BW=roipoly(I,c,r); % roipoly函数选择图像中的多边形区域subplot(1,2,1),imshow(I);subplot(1,2,2),imshow(BW);%% roicolor函数式对RGB图像和灰度图像实现按灰度或亮度值选择区域进行处理a=imread('4.jpg');subplot(2,2,1),imshow(a);I=rgb2gray(a);BW=roicolor(I,128,225); % 按灰度值选择的区域subplot(2,2,4),imshow(BW);%% ploy2mask 函数转化指定的多边形区域为二值掩模x=[63 186 54 190 63];y=[60 60 209 204 601];bw=poly2mask(x,y,256,256); % 转化指定的多边形区域为二值掩模imshow(bw);hold onplot(x,y,'r','LineWidth',2);hold off%% roifilt2函数实现区域滤波a=imread('4.jpg');I=rgb2gray(a);c=[200 250 278 248 199 172];r=[21 21 75 121 121 75];BW=roipoly(I,c,r); % roipoly函数选择图像中的多边形区域h=fspecial('unsharp');J=roifilt2(h,I,BW); % 区域滤波subplot(1,2,1),imshow(I);subplot(1,2,2),imshow(J);%% roifill函数实现对特定区域进行填充a=imread('4.jpg');I=rgb2gray(a);c=[200 250 278 248 199 172];r=[21 21 75 121 121 75];J=roifill(I,c,r); % 对特定区域进行填充subplot(1,2,1),imshow(I);subplot(1,2,2),imshow(J);%}% ----------------图像变换------------------%{% fft2 和ifft2函数分别是计算二维的快速傅里叶变换和反变换f=zeros(100,100);subplot(1,2,1);imshow(f);f(20:70,40:60)=1;subplot(1,2,2);imshow(f);F=fft2(f); % 计算二维的快速傅里叶变换F2=log(abs(F));% 对幅值对对数figure;subplot(1,2,1),imshow(F),colorbar;subplot(1,2,2),imshow(F2),colorbar;%% fftsshift 函数实现了补零操作和改变图像显示象限f=zeros(100,100);subplot(2,2,1),imshow(f);title('f')f(10:70,40:60)=1;subplot(2,2,2),imshow(f);title('f取后')F=fft2(f,256,256);subplot(2,2,3),imshow(F);title('F')F2=fftshift(F); % 实现补零操作subplot(2,2,4),imshow(F2);title('F2')figure,imshow(log(abs(F2)));title('log(|F2|)')%% dct2 函数采用基于快速傅里叶变换的算法,用于实现较大输入矩阵的离散余弦变换% idct2 函数实现图像的二维逆离散余弦变换RGB=imread('drum.jpg');I=rgb2gray(RGB);J=dct2(I); % 对I进行离散余弦变换imshow(log(abs(J))),title('对原图离散后取对数'),colorbar;J(abs(J)<10)=0;K=idct2(J); % 图像的二维逆离散余弦变换figure,imshow(I),title('原灰度图')figure,imshow(K,[0,255]);title('逆离散变换');%% dctmtx 函数用于实现较小输入矩阵的离散余弦变figure;RGB=imread('4.jpg');I=rgb2gray(RGB);subplot(3,2,1),imshow(I),title('原灰度图');I=im2double(I);subplot(3,2,2),imshow(I),title('取双精度后');T=dctmtx(8); % 离散余弦变换subplot(3,2,3),imshow(I),title('离散余弦变换后');B=blkproc(I,[8,8],'P1*x*P2',T,T');subplot(3,2,4),imshow(B),title('blkproc作用I后的B');mask=[ 1 1 1 1 0 0 0 01 1 1 0 0 0 0 01 1 0 0 0 0 0 01 0 0 0 0 0 0 00 0 0 0 0 0 0 00 0 0 0 0 0 0 00 0 0 0 0 0 0 00 0 0 0 0 0 0 0 ];B2=blkproc(B,[8,8],'P1.*x',mask);subplot(3,2,5),imshow(B2),title('blkproc作用B后的B2');I2=blkproc(B2,[8,8],'P1*x*P2',T',T);subplot(3,2,6),imshow(I2),title('blkproc作用B2后的I2');%% edge函数用于提取图像的边缘RGB=imread('4.jpg');I=rgb2gray(RGB);BW=edge(I);imshow(I);figure,imshow(BW);%% radon 函数用来计算指定方向上图像矩阵的投影RGB=imread('4.jpg');I=rgb2gray(RGB);BW=edge(I);theta=0:179;[R,XP]=radon(BW,theta); % 图像矩阵的投影figure,imagesc(theta,XP,R);colormap(hot);xlabel('\theta(degrees)');ylabel('x\prime');title('R_{\theta}(x\prime)');colorbar;%}% ----------------图像增强、分割和编码------------------%{% imhist 函数产生图像的直方图A=imread('4.jpg');B=rgb2gray(A);subplot(2,1,1),imshow(B);subplot(2,1,2),imhist(B);%% histeq 函数用于对图像的直方图均衡化A=imread('4.jpg');B=rgb2gray(A);subplot(2,1,1),imshow(B);subplot(2,1,2),imhist(B);C=histeq(B); % 对图像B进行均衡化figure;subplot(2,1,1),imshow(C);subplot(2,1,2),imhist(C);%% filter2 函数实现均值滤波a=imread('4.jpg');I=rgb2gray(a);subplot(2,2,1),imshow(I);K1=filter2(fspecial('average',3),I)/255; % 3*3的均值滤波K2=filter2(fspecial('average',5),I)/255; % 5*5的均值滤波K3=filter2(fspecial('average',7),I)/255; % 7*7的均值滤波subplot(2,2,2),imshow(K1);subplot(2,2,3),imshow(K2);subplot(2,2,4),imshow(K3);%% wiener2 函数实现Wiener(维纳)滤波a=imread('4.jpg');I=rgb2gray(a);subplot(2,2,1),imshow(I);K1=wiener2(I,[3,3]); % 3*3 wiener滤波K2=wiener2(I,[5,5]); % 5*5 wiener滤波K3=wiener2(I,[7,7]); % 7*7 wiener滤波subplot(2,2,2),imshow(K1);subplot(2,2,3),imshow(K2);subplot(2,2,4),imshow(K3);%% medfilt2 函数实现中值滤波a=imread('4.jpg');I=rgb2gray(a);subplot(2,2,1),imshow(I);K1=medfilt2(I,[3,3]); % 3*3 中值滤波K2=medfilt2(I,[5,5]); % 5*5 中值滤波K3=medfilt2(I,[7,7]); % 7*7 中值滤波subplot(2,2,2),imshow(K1);subplot(2,2,3),imshow(K2);subplot(2,2,4),imshow(K3);%}% ----------------图像模糊及复原------------------%{% deconvwnr 函数:使用维纳滤波器I=imread('qier.jpg');imshow(I);% 对图像进行模糊处理LEN=31;THETA=11;PSF1=fspecial('motion',LEN,THETA); % 运动模糊PSF2=fspecial('gaussian',10,5); % 高斯模糊Blurred1=imfilter(I,PSF1,'circular','conv'); % 得到运动模糊图像Blurred2=imfilter(I,PSF2,'conv'); % 得到高斯噪声模糊图像figure;subplot(1,2,1);imshow(Blurred1);title('Blurred1--"motion"'); subplot(1,2,2);imshow(Blurred2);title('Blurred2--"gaussian"');% 对模糊图像加噪声V=0.002;BlurredNoisy1=imnoise(Blurred1,'gaussian',0,V); % 加高斯噪声BlurredNoisy2=imnoise(Blurred2,'gaussian',0,V); % 加高斯噪声figure;subplot(1,2,1);imshow(BlurredNoisy1);title('BlurredNoisy1'); subplot(1,2,2);imshow(BlurredNoisy2);title('BlurredNoisy2');% 进行维纳滤波wnr1=deconvwnr(Blurred1,PSF1); % 维纳滤波wnr2=deconvwnr(Blurred2,PSF2); % 维纳滤波figure;subplot(1,2,1);imshow(wnr1);title('Restored1,True PSF'); subplot(1,2,2);imshow(wnr2);title('Restored2,True PSF');%% deconvreg函数:使用约束最小二乘滤波器I=imread('qier.jpg');imshow(I);% 对图像进行模糊处理LEN=31;THETA=11;PSF1=fspecial('motion',LEN,THETA); % 运动模糊PSF2=fspecial('gaussian',10,5); % 高斯模糊Blurred1=imfilter(I,PSF1,'circular','conv'); % 得到运动模糊图像Blurred2=imfilter(I,PSF2,'conv'); % 得到高斯噪声模糊图像figure;subplot(1,2,1);imshow(Blurred1);title('Blurred1--"motion"');subplot(1,2,2);imshow(Blurred2);title('Blurred2--"gaussian"');% 对模糊图像加噪声V=0.002;BlurredNoisy1=imnoise(Blurred1,'gaussian',0,V); % 加高斯噪声BlurredNoisy2=imnoise(Blurred2,'gaussian',0,V); % 加高斯噪声figure;subplot(1,2,1);imshow(BlurredNoisy1);title('BlurredNoisy1');subplot(1,2,2);imshow(BlurredNoisy2);title('BlurredNoisy2');NP=V*prod(size(I));reg1=deconvreg(BlurredNoisy1,PSF1,NP); % 约束最小二乘滤波reg2=deconvreg(BlurredNoisy2,PSF2,NP); % 约束最小二乘滤波figure;subplot(1,2,1);imshow(reg1);title('Restored1 with NP');subplot(1,2,2);imshow(reg2);title('Restored2 with NP');%% deconvlucy函数:使用Lucy-Richardson滤波器I=imread('qier.jpg');imshow(I);% 对图像进行模糊处理LEN=31;THETA=11;PSF1=fspecial('motion',LEN,THETA); % 运动模糊PSF2=fspecial('gaussian',10,5); % 高斯模糊Blurred1=imfilter(I,PSF1,'circular','conv'); % 得到运动模糊图像Blurred2=imfilter(I,PSF2,'conv'); % 得到高斯噪声模糊图像figure;subplot(1,2,1);imshow(Blurred1);title('Blurred1--"motion"');subplot(1,2,2);imshow(Blurred2);title('Blurred2--"gaussian"');% 对模糊图像加噪声V=0.002;BlurredNoisy1=imnoise(Blurred1,'gaussian',0,V); % 加高斯噪声BlurredNoisy2=imnoise(Blurred2,'gaussian',0,V); % 加高斯噪声figure;subplot(1,2,1);imshow(BlurredNoisy1);title('BlurredNoisy1');subplot(1,2,2);imshow(BlurredNoisy2);title('BlurredNoisy2');luc1=deconvlucy(BlurredNoisy1,PSF1,5); % 使用Lucy-Richardson滤波luc2=deconvlucy(BlurredNoisy1,PSF1,15); % 使用Lucy-Richardson滤波figure;subplot(1,2,1);imshow(luc1);title('Restored Image,NUMIT=5'); subplot(1,2,2);imshow(luc2);title('Restored Image,NUMIT=15');%}% deconvblind 函数:使用盲卷积算法a=imread('4.jpg');I=rgb2gray(a);figure;imshow(I);title('Original Image');PSF=fspecial('motion',13,45); % 运动模糊figure;imshow(PSF);Blurred=imfilter(I,PSF,'circ','conv'); % 得到运动模糊图像figure;imshow(Blurred);title('Blurred Image');INITPSF=ones(size(PSF));[J,P]=deconvblind(Blurred,INITPSF,30); % 使用盲卷积figure;imshow(J);figure;imshow(P,[],'notruesize');% *-*--*-*-*-*-*-*-*-*-*-*-*图像处理*-*-*-*-*-*-*-*-*-*-*-* %{% 对图像进行减采样a=imread('lena.jpg');%subplot(1,4,1);figure;imshow(a);title('原图');b=rgb2gray(a);%subplot(1,4,2);figure;imshow(b);title('原图的灰度图');[wid,hei]=size(b);%---4倍减采样----quartimg=zeros(wid/2+1,hei/2+1);i1=1;j1=1;for i=1:2:widfor j=1:2:heiquartimg(i1,j1)=b(i,j);j1=j1+1;endi1=i1+1;j1=1;end%subplot(1,4,3);figure;imshow(uint8(quartimg));title('4倍减采样')% ---16倍减采样---quanrtimg=zeros(wid/4+1,hei/4+1);i1=1;j1=1;for i=1:4:widfor j=1:4:heiquanrtimg(i1,j1)=b(i,j);j1=j1+1;endi1=i1+1;j1=1;end%subplot(1,4,4);.figure;imshow(uint8(quanrtimg));title('16倍减采样');%}% 图像类型% 将图像转换为256级灰度图像,64级灰度图像,32级灰度图像,8级灰度图像,2级灰度图像a=imread('4.jpg');%figure;subplot(2,3,1);imshow(a);title('原图');b=rgb2gray(a); % 这是256灰度级的图像%figure;subplot(2,3,2);imshow(b);title('原图的灰度图像');[wid,hei]=size(b);img64=zeros(wid,hei);img32=zeros(wid,hei);img8=zeros(wid,hei);img2=zeros(wid,hei);for i=1:widfor j=j:heiimg64(i,j)=floor(b(i,j)/4); % 转化为64灰度级endend%figure;subplot(2,3,3);imshow(uint8(img64),[0,63]);title('64级灰度图像');for i=1:widfor j=1:heiimg32(i,j)=floor(b(i,j)/8);% 转化为32灰度级endend%figure;subplot(2,3,4);imshow(uint8(img32),[0,31]);title('32级灰度图像');for i=1:widfor j=1:heiimg8(i,j)=floor(b(i,j)/32);% 转化为8灰度级endend%figure;subplot(2,3,5);imshow(uint8(img8),[0,7]);title('8级灰度图像');for i=1:widfor j=1:heiimg2(i,j)=floor(b(i,j)/128);% 转化为2灰度级endend%figure;subplot(2,3,6);imshow(uint8(img2),[0,1]);title('2级灰度图像');% *-*--*-*-*-*-*-*-*-*-*-*-*图像处理*-*-*-*-*-*-*-*-*-*-*-* %{% ------------------ 图像的点运算------------------I=imread('lena.jpg');figure;subplot(1,3,1);imshow(I);title('原图的灰度图');J=imadjust(I,[0.3;0.6],[0.1;0.9]); % 设置灰度变换的范围subplot(1,3,2);imshow(J);title('线性扩展');I1=double(I); % 将图像转换为double类型I2=I1/255; % 归一化此图像C=2; % 非线性扩展函数的参数K=C*log(1+I2); % 对图像的对数变换subplot(1,3,3);imshow(K);title('非线性扩展');M=255-I;figure;subplot(1,3,1);imshow(M);title('灰度倒置');N1=im2bw(I,0.4); % 将此图像二值化,阈值为0.4N2=im2bw(I,0.7); % 将此图像二值化,阈值为0.7 subplot(1,3,2);imshow(N1);title('二值化阈值0.4');subplot(1,3,3);imshow(N2);title('二值化阈值0.7');%}%{% ------------------ 图像的代数运算------------------% 将两幅图像进行加法运算I=imread('lena.jpg');I=rgb2gray(I);J=imread('rice.png');% 以下把两幅图转化为大小一样for i=1:size(I)for j=size(J):size(I)J(i,j)=0;endendI=im2double(I); % 将图像转化为double型J=im2double(J);% imshow(I);figure;imshow(J);K=I+0.3*J; % 将两幅图像相加subplot(1,3,1);imshow(I);title('人物图');subplot(1,3,2);imshow(J);title('背景图');subplot(1,3,3);imshow(K);title('相加后的图');imwrite(K,'i_lena1.jpg');%%% 将两幅图像做减运算,分离背景与原图A=imread('i_lena1.jpg');B=imread('rice.png');% 以下把两幅图转化为大小一样for i=1:size(A)for j=size(B):size(A)B(i,j)=0;endendC=A-0.3*B;a=imread('lena.jpg');subplot(2,2,1);imshow(a);title('原图图');subplot(2,2,2);imshow(A);title('混合图');subplot(2,2,3);imshow(B);title('背景图');subplot(2,2,4);imshow(C);title('分离后的图');%% 设置掩模,需要保留下来的区域,掩模图像的值为1,否则为0 A=imread('drum.jpg');A=rgb2gray(A);A=im2double(A);sizeA=size(A);subplot(1,2,1);imshow(A);title('原图');B=zeros(sizeA(1),sizeA(2)); % 设置模板B(100:400,100:500)=1;K=A.*B; % 两幅图像相乘subplot(1,2,2);imshow(K);title('局部图');%}%{% ------------------ 图像的缩放------------------A=imread('drum.jpg');B1=imresize(A,1.5); % 比例放大1.5杯,默认采用的是最近邻法进行线性插值B2=imresize(A,[420 384]); % 非比例放大到420:384C1=imresize(A,0.7); % 比例缩小0.7倍C2=imresize(A,[150 180]); % 非比例缩小到150:180figure;imshow(B1);title('比例放大图');figure;imshow(B2);title('非比例放大图');figure;imshow(C1);title('比例缩小图');figure;imshow(C2);title('非比例缩小图');% 检测非比例缩放得到的图片是否能还原到原图a=size(A)d=imresize(C2,[a(1),a(2)]);figure;imshow(d);%}% ------------------ 图像的旋转------------------I=imread('drum.jpg');J=imrotate(I,45); % 图像进行逆时针旋转,默认采用最近邻插值法进行插值处理K=imrotate(I,90); % 默认旋转出界的部分不被截出subplot(1,3,1);imshow(I);subplot(1,3,2);imshow(J);subplot(1,3,3);imshow(K);% 检测旋转后的图像是否失真P=imrotate(K,270);figure;imshow(P);。

VC++绘图编程

VC++绘图编程

8
绘制线条
移动画笔位置 成员函数MoveTo() 用CDC成员函数 成员函数 pDC->MoveTo(x1,y1) ; 绘制直线 成员函数LineTo() 用CDC成员函数 成员函数 pDC->LineTo(x2,y2) ; 演示程序: 使用 使用CPen画线 画线.avi> 演示程序: <使用 画线
演示程序: 演示程序:画线函数处理.avi
11
画光栅点
pDC->SetPixel(x,y,(COLORREF)x+y);
COLORREF SetPixel( int x, int y, COLORREF crColor );
Parameters x
Specifies the logical x-coordinate of the point to be set.
演示程序:图形操作/画图形 演示程序:图形操作 画图形 Program 第三章图象编程 第三章图象编程.cpp-OnDrawGraph () -
14
写文字
pDC->TextOut(100,200,strText,lstrlen(strText);
virtual BOOL TextOut( int x, int y, LPCTSTR lpszString, int nCount ); Parameters x
用笔( 对象) 用笔(CPen对象)绘制宽度为 点红色的实线 对象 绘制宽度为5点红色的实线
void CImageView::OnDraw(CDC* pDC) { … CPen penBlue(PS_SOLID,5,RGB(255,0,0)),*pOldPen; pOldPen=pDC->SelectObject(&penBlue); pDC->MoveTo(20,10); pDC->LineTo(200,100); pDC->SelectObject(pOldPen); penBlue.DeleteObject(); }

应用CImage类用文件和流的方式显示图片和放大缩小图片

应用CImage类用文件和流的方式显示图片和放大缩小图片

应⽤CImage类⽤⽂件和流的⽅式显⽰图⽚和放⼤缩⼩图⽚1.是MFC⼯程2.创建默认⼯程:单⽂档⼯程3.⼯程名:JPEGTest4.1在CJPEGTestView类中添加HANDLE m_hFile;CImage m_Image;void LoadMemImage( void * pMemData, long len);afx_msg void OnFileOpen();4.2在stdafx.h中添加#include4.3在CJPEGTestView.cpp中添加BEGIN_MESSAGE_MAP(CJPEGTestView, CView)ON_COMMAND(ID_FILE_OPEN, &CJPEGTestView::OnFileOpen)//这个是添加的END_MESSAGE_MAP()4.4void CJPEGTestView::OnFileOpen(){CString strFilter;CSimpleArray aguidFileTypes;HRESULT hResult;// 获取CImage⽀持的图像⽂件的过滤字符串hResult = m_Image.GetExporterFilterString(strFilter,aguidFileTypes,_T( "All Image Files") );if ( FAILED(hResult) ){MessageBox(_T("GetExporterFilter调⽤失败!"));return;}CFileDialog dlg( TRUE, NULL, NULL, OFN_FILEMUSTEXIST, strFilter );if ( IDOK != dlg.DoModal() )return;m_Image.Destroy();{//在此处是⽤流的⽅式显⽰JPEGm_hFile = ::CreateFile(dlg.GetFileName(),GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_READONLY,NULL); // ⽤这个函数⽐OpenFile好if ( m_hFile == INVALID_HANDLE_VALUE){MessageBox(_T("打开⽂件失败"));CloseHandle( m_hFile ); // ⼀定注意在函数退出之前对句柄进⾏释放。

高新技术考试科目

高新技术考试科目

高新考试ETX5.3平台考试注意事项
1、系统版本:ETX5.3
2、启动管理机后请完成系统提示的更新,并上传更新报告,以确保考试系统为最新版本
3、请先安装考试系统后再在管理机安装正式题库进行考试
4、如果考生输入准考证号码后显示“系统找不到指定路径”,请检查该科目题库是否在管理机上正确安装
5、考试过程中碰到死机情况请重启机器解决(还原卡必须处于不保护状态)
6、ETX系统软件类操作题均为人工开启软件环境而非考试机自动调用,请选择正确的应用软件进行考试
7、当试题涉及多个软件时,请考生自己手动打开其应用软件;答题完成后请务必关闭应用软件再进行下一题操作。

8、试考科目无需安装题库,直接下载试卷即可。

9、考试结束后请考点将通过管理机中的"辅助"菜单下的"备份单机"功能将每台考试机的单机备份及应用服务器目录下C:\ATA\ata002\ExamServer\cj及database文件夹内容备份一个月,以备待查。

10、官方下载地址:ftp://033sgld30:Ata1234@。

VC++_GDI+编程详解

VC++_GDI+编程详解

VC下使用GDI+进行图像程序设计孙涛整理/suntaoznz目录GDI+介绍 (3)1. GDI+的三个部分 (3)2. 基于类的接口结构 (4)GDI+的新增特性? (4)1. 新特性 (4)2.编程模式的变化 (7)直线、曲线和图形 (10)1. 矢量图形概述 (11)2. 钢笔、直线和矩形 (12)3.椭圆和弧线 (13)4.多边形 (14)5. 基数样条 (14)6. 贝塞尔样条 (15)7. 路径 (16)8. 画笔和填充的形状 (18)9. 打开的曲线和闭合的曲线 (21)10. 区域 (22)11. 剪辑 (23)12.拉平路径 (24)13. 用直线和曲线消除锯齿 (24)图像、位图和图元文件 (25)1. 位图类型 (25)2.图元文件 (28)3.绘制、定位和克隆图像 (29)4. 裁切和缩放图像 (31)坐标系统和变形 (32)1. 坐标系统类型 (32)2.变形的矩阵表示形式 (35)3.全局变形和局部变形 (39)图形容器 (41)GDI+介绍Microsoft® Windows® GDI+ 是Windows XP 或者Windows Server 2003 操作系统的子系统。

它负责在屏幕和打印机上显示信息。

GDI+ 是一个应用程序编程接口,它是一个C++ 类。

如同它的名字暗示一样,GDI+ 是Windows 图形设备接口(GDI)的继承者, 这个图形设备接口包括早期的Windows版本。

Windows XP 或者Windows Server 2003 为了支持以前的应用程序还支持GDI,但是新的应用程序开发人员应该去使用GDI+ 去作他们的图像处理工作。

因为GDI+对GDI的很多性能进行了优化,同时还提供了其他的一些特性。

一个图形设备接口,例如GDI+, 允许应用程序开发人员在打印机或屏幕上显示信息,而不用去考虑显示设备的具体细节。

应用程序开发人员调用GDI+ classes 提供的方法(methods),这些方法将依次传到指定的设备驱动程序上。

VC6和MATCOM来开发图像处理程序

VC6和MATCOM来开发图像处理程序

VC6.0和MATCOM来开发图像处理程序作者:彭军(心の诚)博客:/pengjun一、软件环境1、MA TLAB安装的版本没有什么限制,可以安装也可以不安装。

但是最好知道一些MA TLAB函数的调用方式和数据类型等,对于你使用MA TCOM有很好的帮助。

2、MA TCOM4.5这个软件可厉害了,可以让你在VC6.0中使用类似与MA TLAB的语句,只是做一些稍微的更改就可以了。

不过,他支持的函数是有限的,可以查看帮助来看支持的文件。

他生成的exe可执行文件可以在没有安装MA TLAB的地方运行,只是需要几个dll文件而已。

如果用MA TLAB的Depolyment Tool来生成的exe可执行文件,在没有安装MA TLAB的机子上运行时需要安装MCR,而MCR现在有200M多,所以很不方便。

3、VC++6.0这个就没什么可说的了,安装就可以了。

注意的是最好选择注册环境变量(Registed Enviroment variables)。

二、MATCOM4.5的安装1、下载地址:/yunbo/matcom4.5.rar2、MA TCOM4.5在安装时需要你输入口令,Matcom4.5的口令为FREE-4.5-1193046-802951113、第一次运行MA TCOM时会有提示是否自动搜索VC6.0的cl.exe,如果你已经安装了VC6.0的话,那么它会自动找到。

这个VC6.0是必须安装的,如果你先安装的MA TCOM,后安装的VC6也没关系,只用安装VC6之后启动MA TCOM就可以了。

然后会提示是否安装了MA TLAB,如果安装了就点“是”,否则就点“否”。

4、如果安装了MA TLAB的话,会有下面的操作:点击“是”之后,启动MA TLAB,输入下面的命令:cd c:\matcom45 % MA Tcom的安装路径diary mpathmatlabpathdiary off用上面的目的是为了让MA TCOM能记录MA TLAB的路径。

在VC_中使用Kodak图像编辑控件

在VC_中使用Kodak图像编辑控件

收稿日期:2000 09 19作者简介:丁有和,1969 ,硕士,南京师范大学电气与电子工程学院讲师,主要研究方向为CAD/CA M.在VC ++中使用Kodak 图像编辑控件丁有和(南京师范大学电气与电子工程学院,南京,210042)[摘要] 重点讨论Kodak 图像编辑控件在VC++中的使用方法及其功能的实现.[关键词] VC ++;图像控件;Kodak;ActiveX 控件[中图分类号]TP317.4; [文献标识码]B; [文章编号]1008 1925(2001)03 0063 03众所周知,Visual C++[1]的静态Picture 控制功能是比较弱的,它只能显示出在资源中的图标、位图、光标以及图元文件的内容,而不像VB 在Image 控件可以显示出绝大多数的外部图像文件(B MP 、GIF 、JPEG 等).因此,想要在VC++对话框或其他窗口中显示外部图像文件则只能借助于第三方提供的控件.Kodak 图像控件组就是一组非常专业、适用并随Windows 98一起安装,由Eastman Software 公司提供给Microsoft 的32位ActiveX 控件.该控件组包括Kodak 图像编辑、管理、批注、扫描及缩略图控件,它们能处理AWD(传真文档,仅用于Windows 98)、B MP 、DCX 、JPG 、PCX 、TIFF 、XIF 、GI F 、WIFF 等类型的图像文件,并提供了批注、裁剪、缩放、滚动、剪贴板操作以及许多常用图像文件管理功能.文献[2]中虽对Kodak 缩略图控件作了一些论述,但这里着重讨论Kodak 图像编辑控件在VC++中的使用方法及其功能的实现.1 一般使用方法Kodak 图像编辑控件兼有图像处理和批注的功能.在Visual C++中插入图像编辑控件的操作方法和其它普通的Ac tiveX 控件一样,一般都遵循下面的过程(以基于对话框程序为例):创建一个基于对话框的项目ImgDemo.选择 Project Add To Pojec t Components and C ontrols 菜单,弹出 Components and C ontrols 对话框.在此对话框中选择 Registered ActiveX Controls ,将 Kodak 图像编辑控件 组件相关的 类 插入.打开IDD_I MGDEMO_DIALOG 对话框资源模板,并添加 Kodak 图像编辑控件 ,保留其缺省的ID 号.删除 取消 按钮,将 确定 按钮的标题改为 退出 ,再添加 打开 按钮(ID_I MAGE _OPEN).用ClassWizard 为Kodak 图像编辑控件添加成员变量m_ImgEdit,为 打开 按钮增加B N_CLIC KED 消息处理,并添加下列代码:第1卷第3期2001年南京师大学报(工程技术版)JOURNAL OF NANJING NORMAL UNIVERSITY(E NGINEERING AND TEC HNOLOGY)Vol.1No.32001void CImgDemoDlg::OnImgOpen(){CFileDialog dlg(TRUE);dlg.m_ofn.lpstrFilter= 所有图像\0*.bmp;*.gif;*.jpg;*.pcx;*.tif \0\所有文件(*.*)\0*.*\0\0 ;if(dlg.DoModal()==IDOK){m_ImgEdit.SetImage(dlg.GetPathNa me()); //设置控件相关联的图像m_ImgEdit.SetPage(1);//设置图像显示页面m_ImgEdit.Display();//显示图像}}运行并测试,结果如图1所示.图2 页面属性 图对话框1 例ImgDemo 运行结果2 图像处理Kodak 图像编辑控件能对显示的图像进行复制和粘贴、旋转和倒置、缩放和滚动等操作,其相关的操作函数(方法)如表1所示.表1 Kodak 图像编辑控件的常用图像操作操作函数功能描述复制和粘贴ClipboardCopyClipboardCutClipboardPas teCompletePas te将用户选择的图像区域内容和批注复制到剪贴板中将用户选择的图像区域内容和批注剪切到剪贴板中将剪贴板中的数据粘贴到指定位置处将剪贴板中的数据完全粘贴到控件所在的全部区域旋转和倒置RotateLeftRotateRightFlip向左旋转图像向右旋转图像倒置图像缩放和滚动Fi tToZoom ToSelecti onSetZoomScrollImage 改变图像在控件窗口显示的比例将选定的区域放大至整个控件窗口设置从2到6554的显示比例百分数滚动图像需要说明的是,在表1操作函数中,有许多参数是VARIANT 数据类型.该类型广泛用于ActiveX 中,使用时要注意设置VARI ANT 变量的具体类型.例如:南京师大学报(工程技术版)第1卷第3期(2001年)VARIAN T vb;vb.vt=VT_BOO L; //设置具体的数值类型为BO OLvb.boolVal=TRUE;m_ImgEdi t.Fit To(1,vb);但对于VARI ANT 的字符串型变量来说,一般不能直接对其赋值,这时可以用MFC 的COLeVariant 进行转换,例如:COlE Vari ant vb( MyString ); //直接构造除了使用上述操作函数外,用户还可用VC++的ClassWizard 映射控件相关的消息(事件)来执行自己的代码.例如若映射控件的SelectionRectDrawn 消息,并添加下列代码:void CImgDemoDl g::OnSelectionRectDrawnEdi tctrl1(long Left,long Top,long Wi dth,long Height){m_ImgEdi t.Z oomToSelec tion();m_ImgEdi t.DeleteSelectedAnnotations(); //取消用户选定的区域}则当用户的在控件窗口中用鼠标划定某个区域后,将自动调用ZoomToSelec tion 函数来放大显示图像.当然,用户也可调用Sho wPageProperties 函数显示 页面属性 对话框,用来设置当前显示页图像的调色板、压缩方式以及显示分辨率和大小,如图2所示.3 图像批注图像批注是Kodak 图像编辑控件的非常引人注目的一大特色,它能让用户从图3所示的 批注工具箱 中选择一个工具在图像中进行批注.图4 橡皮戳 图属性对话框3 批注工具箱 具体批注时一般可采用下列步骤:首先调用AddAnnotationGroup 函数添加一个新的批注层.然后再调用SelectAnnotationGroup 将刚才添加的新批注层设为当前批注层.调用SelectTool 函数选择一个批注工具,这时用户就可在显示的图像中进行批注了.调用BurnInAnnotations 将当前批注作永久保留,或调用Hide AnnotationGroup 等函数对指定批注层进行隐藏等操作.需要说明的是:当用户选择 文件中的文本 工具进行批注时,它还将弹出 选择文本文件 对话框让用户指定某个文本文件.在决定使用 橡皮戳 批注工具前,用户必须调用SetRubberStampItem 函数设置橡皮戳菜丁有和:在VC++中使用Kodak 图像编辑控件南京师大学报(工程技术版)第1卷第3期(2001年)单中某个菜单项(具体的菜单项可通过GetRubberStampMenuIte ms获得)方能进行橡皮戳批注.若嫌此过程比较复杂且不够直观,用户也可直接调用ShowRubberStampDialog函数来显示如图4的对话框,当用户选择其中的橡皮戳选项,并按 确定 按钮后,就可用此橡皮戳进行批注了.至此,用户可根据以上论述方便地在VC++中使用Kodak图像编辑控件了.[参考文献][1] 丁有和.Visual C++程序员基础教程[M].山东:青岛出版社,1999[2] 丁有和.Visual C++图形图像编程技巧[M].山东:青岛出版社,2000Application of Kodak Image Edit Control to Visual C++D ing Youhe(College of Elec tronic and Electrical Engineeri ng,Nanjing Normal Universi ty,Nanjing,210042,PRC)Abstract:This paper discusses the application of the Kodak image edit control to Visual C++and functional i mplementation.Key words:VC++,i mage controls,Kodak,activeX controls(责任编辑:严海琳)(上接第62页)[2] Bellcore.GR-30-CORE[Z].Issue1.December.1994[3] GB15279-94.自动电话机技术条件[S]A kind of110Reporting-to-police System Based onCity Telephone Subscriber LineSun qichang,Shi Bing,Liu Guojin(Center for Analysi s and Measurement,Nanjing Normal Univers ity,Nanji ng,210097,PRC)Abstract:The Content of thi s article is about a desi gn scheme of a110rep orting-to-police system based on ci ty telephone subscriber Line.By using the service work that the telecommunication bureau provides caller information to subscriber (inserts caller nu mber and other relevan t information between the first and the second ringing of the subscriber terminal), this scheme sets up a platform using binary frequency shi ft keying(FSK)decode technique on the subscriber side,receives the caller(reporting side)telephone number,then through the data base in the service equip ment,finds the caller (reporting side)material and information,and chooses the corresponding police action plan.Key words:caller number,binary frequency shi ft keying(FSK),110reporting-to-police system(责任编辑:严海琳)。

(完整版)数字图像处理代码大全

(完整版)数字图像处理代码大全

1.图像反转MATLAB程序实现如下:I=imread('xian.bmp');J=double(I);J=-J+(256-1); %图像反转线性变换H=uint8(J);subplot(1,2,1),imshow(I);subplot(1,2,2),imshow(H);2.灰度线性变换MATLAB程序实现如下:I=imread('xian.bmp');subplot(2,2,1),imshow(I);title('原始图像');axis([50,250,50,200]);axis on; %显示坐标系I1=rgb2gray(I);subplot(2,2,2),imshow(I1);title('灰度图像');axis([50,250,50,200]);axis on; %显示坐标系J=imadjust(I1,[0.1 0.5],[]); %局部拉伸,把[0.1 0.5]内的灰度拉伸为[0 1]subplot(2,2,3),imshow(J);title('线性变换图像[0.1 0.5]');axis([50,250,50,200]);grid on; %显示网格线axis on; %显示坐标系K=imadjust(I1,[0.3 0.7],[]); %局部拉伸,把[0.3 0.7]内的灰度拉伸为[0 1]subplot(2,2,4),imshow(K);title('线性变换图像[0.3 0.7]');axis([50,250,50,200]);grid on; %显示网格线axis on; %显示坐标系3.非线性变换MATLAB程序实现如下:I=imread('xian.bmp');I1=rgb2gray(I);subplot(1,2,1),imshow(I1);title('灰度图像');axis([50,250,50,200]);grid on; %显示网格线axis on; %显示坐标系J=double(I1);J=40*(log(J+1));H=uint8(J);subplot(1,2,2),imshow(H);title('对数变换图像');axis([50,250,50,200]);grid on; %显示网格线axis on; %显示坐标系4.直方图均衡化MATLAB程序实现如下:I=imread('xian.bmp');I=rgb2gray(I);figure;subplot(2,2,1);imshow(I);subplot(2,2,2);imhist(I);I1=histeq(I);figure;subplot(2,2,1);imshow(I1);subplot(2,2,2);imhist(I1);5.线性平滑滤波器用MATLAB实现领域平均法抑制噪声程序:I=imread('xian.bmp');subplot(231)imshow(I)title('原始图像')I=rgb2gray(I);I1=imnoise(I,'salt & pepper',0.02);subplot(232)imshow(I1)title('添加椒盐噪声的图像')k1=filter2(fspecial('average',3),I1)/255; %进行3*3模板平滑滤波k2=filter2(fspecial('average',5),I1)/255; %进行5*5模板平滑滤波k3=filter2(fspecial('average',7),I1)/255; %进行7*7模板平滑滤波k4=filter2(fspecial('average',9),I1)/255; %进行9*9模板平滑滤波subplot(233),imshow(k1);title('3*3模板平滑滤波');subplot(234),imshow(k2);title('5*5模板平滑滤波');subplot(235),imshow(k3);title('7*7模板平滑滤波');subplot(236),imshow(k4);title('9*9模板平滑滤波'); 6.中值滤波器用MATLAB实现中值滤波程序如下:I=imread('xian.bmp');I=rgb2gray(I);J=imnoise(I,'salt&pepper',0.02);subplot(231),imshow(I);title('原图像');subplot(232),imshow(J);title('添加椒盐噪声图像');k1=medfilt2(J); %进行3*3模板中值滤波k2=medfilt2(J,[5,5]); %进行5*5模板中值滤波k3=medfilt2(J,[7,7]); %进行7*7模板中值滤波k4=medfilt2(J,[9,9]); %进行9*9模板中值滤波subplot(233),imshow(k1);title('3*3模板中值滤波'); subplot(234),imshow(k2);title('5*5模板中值滤波'); subplot(235),imshow(k3);title('7*7模板中值滤波'); subplot(236),imshow(k4);title('9*9模板中值滤波'); 7.用Sobel算子和拉普拉斯对图像锐化:I=imread('xian.bmp');subplot(2,2,1),imshow(I);title('原始图像');axis([50,250,50,200]);grid on; %显示网格线axis on; %显示坐标系I1=im2bw(I);subplot(2,2,2),imshow(I1);title('二值图像');axis([50,250,50,200]);grid on; %显示网格线axis on; %显示坐标系H=fspecial('sobel'); %选择sobel算子J=filter2(H,I1); %卷积运算subplot(2,2,3),imshow(J);title('sobel算子锐化图像');axis([50,250,50,200]);grid on; %显示网格线axis on; %显示坐标系h=[0 1 0,1 -4 1,0 1 0]; %拉普拉斯算子J1=conv2(I1,h,'same'); %卷积运算subplot(2,2,4),imshow(J1);title('拉普拉斯算子锐化图像');axis([50,250,50,200]);grid on; %显示网格线axis on; %显示坐标系8.梯度算子检测边缘用MATLAB实现如下:I=imread('xian.bmp');subplot(2,3,1);imshow(I);title('原始图像');axis([50,250,50,200]);grid on; %显示网格线axis on; %显示坐标系I1=im2bw(I);subplot(2,3,2);imshow(I1);title('二值图像');axis([50,250,50,200]);grid on; %显示网格线axis on; %显示坐标系I2=edge(I1,'roberts');figure;subplot(2,3,3);imshow(I2);title('roberts算子分割结果');axis([50,250,50,200]);grid on; %显示网格线axis on; %显示坐标系I3=edge(I1,'sobel');subplot(2,3,4);imshow(I3);title('sobel算子分割结果');axis([50,250,50,200]);grid on; %显示网格线axis on; %显示坐标系I4=edge(I1,'Prewitt');subplot(2,3,5);imshow(I4);title('Prewitt算子分割结果');axis([50,250,50,200]);grid on; %显示网格线axis on; %显示坐标系9.LOG算子检测边缘用MATLAB程序实现如下:I=imread('xian.bmp');subplot(2,2,1);imshow(I);title('原始图像');I1=rgb2gray(I);subplot(2,2,2);imshow(I1);title('灰度图像');I2=edge(I1,'log');subplot(2,2,3);imshow(I2);title('log算子分割结果'); 10.Canny算子检测边缘用MATLAB程序实现如下:I=imread('xian.bmp'); subplot(2,2,1);imshow(I);title('原始图像')I1=rgb2gray(I);subplot(2,2,2);imshow(I1);title('灰度图像');I2=edge(I1,'canny'); subplot(2,2,3);imshow(I2);title('canny算子分割结果');11.边界跟踪(bwtraceboundary函数)clcclear allI=imread('xian.bmp');figureimshow(I);title('原始图像');I1=rgb2gray(I); %将彩色图像转化灰度图像threshold=graythresh(I1); %计算将灰度图像转化为二值图像所需的门限BW=im2bw(I1, threshold); %将灰度图像转化为二值图像figureimshow(BW);title('二值图像');dim=size(BW);col=round(dim(2)/2)-90; %计算起始点列坐标row=find(BW(:,col),1); %计算起始点行坐标connectivity=8;num_points=180;contour=bwtraceboundary(BW,[row,col],'N',connectivity,num_p oints);%提取边界figureimshow(I1);hold on;plot(contour(:,2),contour(:,1), 'g','LineWidth' ,2); title('边界跟踪图像');12.Hough变换I= imread('xian.bmp');rotI=rgb2gray(I);subplot(2,2,1);imshow(rotI);title('灰度图像');axis([50,250,50,200]);grid on;axis on;BW=edge(rotI,'prewitt');subplot(2,2,2);imshow(BW);title('prewitt算子边缘检测后图像');axis([50,250,50,200]);grid on;axis on;[H,T,R]=hough(BW);subplot(2,2,3);imshow(H,[],'XData',T,'YData',R,'InitialMagnification','fit'); title('霍夫变换图');xlabel('\theta'),ylabel('\rho');axis on , axis normal, hold on;P=houghpeaks(H,5,'threshold',ceil(0.3*max(H(:))));x=T(P(:,2));y=R(P(:,1));plot(x,y,'s','color','white');lines=houghlines(BW,T,R,P,'FillGap',5,'MinLength',7); subplot(2,2,4);,imshow(rotI);title('霍夫变换图像检测');axis([50,250,50,200]);grid on;axis on;hold on;max_len=0;for k=1:length(lines)xy=[lines(k).point1;lines(k).point2];plot(xy(:,1),xy(:,2),'LineWidth',2,'Color','green');plot(xy(1,1),xy(1,2),'x','LineWidth',2,'Color','yellow');plot(xy(2,1),xy(2,2),'x','LineWidth',2,'Color','red');len=norm(lines(k).point1-lines(k).point2);if(len>max_len)max_len=len;xy_long=xy;endendplot(xy_long(:,1),xy_long(:,2),'LineWidth',2,'Color','cyan'); 13.直方图阈值法用MATLAB实现直方图阈值法:I=imread('xian.bmp');I1=rgb2gray(I);figure;subplot(2,2,1);imshow(I1);title('灰度图像')axis([50,250,50,200]);grid on; %显示网格线axis on; %显示坐标系[m,n]=size(I1); %测量图像尺寸参数GP=zeros(1,256); %预创建存放灰度出现概率的向量for k=0:255GP(k+1)=length(find(I1==k))/(m*n); %计算每级灰度出现的概率,将其存入GP中相应位置endsubplot(2,2,2),bar(0:255,GP,'g') %绘制直方图title('灰度直方图')xlabel('灰度值')ylabel('出现概率')I2=im2bw(I,150/255);subplot(2,2,3),imshow(I2);title('阈值150的分割图像')axis([50,250,50,200]);grid on; %显示网格线axis on; %显示坐标系I3=im2bw(I,200/255); %subplot(2,2,4),imshow(I3);title('阈值200的分割图像')axis([50,250,50,200]);grid on; %显示网格线axis on; %显示坐标系14. 自动阈值法:Otsu法用MATLAB实现Otsu算法:clcclear allI=imread('xian.bmp');subplot(1,2,1),imshow(I);title('原始图像')axis([50,250,50,200]);grid on; %显示网格线axis on; %显示坐标系level=graythresh(I); %确定灰度阈值BW=im2bw(I,level);subplot(1,2,2),imshow(BW);title('Otsu法阈值分割图像')axis([50,250,50,200]);grid on; %显示网格线axis on; %显示坐标系15.膨胀操作I=imread('xian.bmp'); %载入图像I1=rgb2gray(I);subplot(1,2,1);imshow(I1);title('灰度图像')axis([50,250,50,200]);grid on; %显示网格线axis on; %显示坐标系se=strel('disk',1); %生成圆形结构元素I2=imdilate(I1,se); %用生成的结构元素对图像进行膨胀subplot(1,2,2);imshow(I2);title('膨胀后图像');axis([50,250,50,200]);grid on; %显示网格线axis on; %显示坐标系16.腐蚀操作MATLAB实现腐蚀操作I=imread('xian.bmp'); %载入图像I1=rgb2gray(I);subplot(1,2,1);imshow(I1);title('灰度图像')axis([50,250,50,200]);grid on; %显示网格线axis on; %显示坐标系se=strel('disk',1); %生成圆形结构元素I2=imerode(I1,se); %用生成的结构元素对图像进行腐蚀subplot(1,2,2);imshow(I2);title('腐蚀后图像');axis([50,250,50,200]);grid on; %显示网格线axis on; %显示坐标系17.开启和闭合操作用MATLAB实现开启和闭合操作I=imread('xian.bmp'); %载入图像subplot(2,2,1),imshow(I);title('原始图像');axis([50,250,50,200]);axis on; %显示坐标系I1=rgb2gray(I);subplot(2,2,2),imshow(I1);title('灰度图像');axis([50,250,50,200]);axis on; %显示坐标系se=strel('disk',1); %采用半径为1的圆作为结构元素I3=imclose(I1,se); %闭合操作subplot(2,2,3),imshow(I2);title('开启运算后图像');axis([50,250,50,200]);axis on; %显示坐标系subplot(2,2,4),imshow(I3);title('闭合运算后图像');axis([50,250,50,200]);axis on; %显示坐标系18.开启和闭合组合操作I=imread('xian.bmp'); %载入图像subplot(3,2,1),imshow(I);title('原始图像');axis([50,250,50,200]);axis on; %显示坐标系I1=rgb2gray(I);subplot(3,2,2),imshow(I1);title('灰度图像');axis([50,250,50,200]);axis on; %显示坐标系se=strel('disk',1);I3=imclose(I1,se); %闭合操作subplot(3,2,3),imshow(I2);title('开启运算后图像');axis([50,250,50,200]);axis on; %显示坐标系subplot(3,2,4),imshow(I3);title('闭合运算后图像');axis([50,250,50,200]);axis on; %显示坐标系se=strel('disk',1);I4=imopen(I1,se);I5=imclose(I4,se);subplot(3,2,5),imshow(I5); %开—闭运算图像title('开—闭运算图像');axis([50,250,50,200]);axis on; %显示坐标系I6=imclose(I1,se);I7=imopen(I6,se);subplot(3,2,6),imshow(I7); %闭—开运算图像title('闭—开运算图像');axis([50,250,50,200]);axis on; %显示坐标系19.形态学边界提取利用MATLAB实现如下:I=imread('xian.bmp'); %载入图像subplot(1,3,1),imshow(I);title('原始图像');axis([50,250,50,200]);grid on; %显示网格线axis on; %显示坐标系I1=im2bw(I);subplot(1,3,2),imshow(I1);title('二值化图像');axis([50,250,50,200]);grid on; %显示网格线axis on; %显示坐标系I2=bwperim(I1); %获取区域的周长subplot(1,3,3),imshow(I2);title('边界周长的二值图像');axis([50,250,50,200]);grid on;axis on;20.形态学骨架提取利用MATLAB实现如下:I=imread('xian.bmp'); subplot(2,2,1),imshow(I); title('原始图像');axis([50,250,50,200]); axis on;I1=im2bw(I);subplot(2,2,2),imshow(I1); title('二值图像');axis([50,250,50,200]); axis on;I2=bwmorph(I1,'skel',1); subplot(2,2,3),imshow(I2); title('1次骨架提取');axis([50,250,50,200]); axis on;I3=bwmorph(I1,'skel',2); subplot(2,2,4),imshow(I3); title('2次骨架提取');axis([50,250,50,200]); axis on;21.直接提取四个顶点坐标I = imread('xian.bmp');I = I(:,:,1);BW=im2bw(I);figureimshow(~BW)[x,y]=getpts。

自己积累的一些EmguCV代码(主要有图片格式转换,图片裁剪,图片翻转,图片旋转和图片平移等功能)

自己积累的一些EmguCV代码(主要有图片格式转换,图片裁剪,图片翻转,图片旋转和图片平移等功能)

⾃⼰积累的⼀些EmguCV代码(主要有图⽚格式转换,图⽚裁剪,图⽚翻转,图⽚旋转和图⽚平移等功能)using System;using System.Drawing;using Emgu.CV;using Emgu.CV.CvEnum;using Emgu.CV.Structure;namespace ZNLGIS{public class ImageClass{//图⽚裁剪public static Image<Bgr, Byte> Cut(Image<Bgr,Byte> image ,Rectangle rectangle){System.Drawing.Size roisize = new Size(260,380);IntPtr dst = CvInvoke.cvCreateImage(roisize, Emgu.CV.CvEnum.IPL_DEPTH.IPL_DEPTH_8U, 3);CvInvoke.cvSetImageROI(image.Ptr, rectangle);CvInvoke.cvCopy(image.Ptr, dst, IntPtr.Zero);return OpenCVEmguCVDotNet.IplImagePointerToEmgucvImage<Bgr, Byte>(dst);}//图⽚裁剪public static Image<Bgr, Byte> Cut2(Image<Bgr,Byte> image,int oldwidth,int oldheight){int x = image.Width - oldwidth;int y = image.Height - oldheight;System.Drawing.Size roisize = new System.Drawing.Size(oldwidth, oldheight); //要裁剪的图⽚⼤⼩IntPtr dst = CvInvoke.cvCreateImage(roisize, Emgu.CV.CvEnum.IPL_DEPTH.IPL_DEPTH_8U, 3);System.Drawing.Rectangle rect = new System.Drawing.Rectangle(x/2, y/2, oldwidth, oldheight);CvInvoke.cvSetImageROI(image.Ptr, rect);CvInvoke.cvCopy(image.Ptr, dst, IntPtr.Zero);return OpenCVEmguCVDotNet.IplImagePointerToEmgucvImage<Bgr, Byte>(dst);}//图⽚翻转public static Image<Bgr, Byte> FlipImage(Image<Bgr, Byte> image, bool isHorizontal){if (isHorizontal){CvInvoke.cvFlip(image.Ptr, IntPtr.Zero, FLIP.HORIZONTAL);}else{CvInvoke.cvFlip(image.Ptr, IntPtr.Zero, FLIP.VERTICAL);}return image;}//图⽚旋转public static Image<Bgr, Byte> RotateImage(Image<Bgr, Byte> image_old, double angle, bool clockwise){IntPtr image_temp;double anglerad = Math.PI * (angle / 180);int newwidth = (int)Math.Abs(image_old.Bitmap.Height * Math.Sin(anglerad)) +(int)Math.Abs(image_old.Bitmap.Width * Math.Cos(anglerad)) + 1;int newheight = (int)Math.Abs(image_old.Bitmap.Height * Math.Cos(anglerad)) +(int)Math.Abs(image_old.Bitmap.Width * Math.Sin(anglerad)) + 1;image_temp = CvInvoke.cvCreateImage(new Size(newwidth, newheight), IPL_DEPTH.IPL_DEPTH_8U, 3);CvInvoke.cvZero(image_temp);int flag = -1;if (clockwise){flag = 1;}float[] m = new float[6];int w = image_old.Bitmap.Width;int h = image_old.Bitmap.Height;m[0] = (float)Math.Cos(flag * angle * Math.PI / 180);m[1] = (float)Math.Sin(flag * angle * Math.PI / 180);m[3] = -m[1];m[4] = m[0];m[2] = w * 0.5f;unsafe{void* p;IntPtr ptr;fixed (float* pc = m){p = (void*)pc;ptr = new IntPtr(p);}IntPtr M = CvInvoke.cvMat(2, 3, MAT_DEPTH.CV_32F, ptr);CvInvoke.cvGetQuadrangleSubPix(image_old.Ptr,image_temp,M);}return OpenCVEmguCVDotNet.IplImagePointerToEmgucvImage<Bgr, Byte>(image_temp);}//图⽚平移public static Image<Bgr, Byte> Py(Image<Bgr, Byte> src,int x,int y){System.Drawing.Size roisize = new Size(src.Width, src.Height);Image<Bgr, Byte> dst = new Image<Bgr, byte>(src.Width, src.Height, new Bgr(Color.Transparent));int i, j;int w = src.Width;int h = src.Height;if (x >= 0 && y >= 0){for (i = 0; i < w - x; i++){for (j = 0; j < h - y; j++){CvInvoke.cvSet2D(dst, j + y, i + x, CvInvoke.cvGet2D(src, j, i));}}}else if (x >= 0 && y < 0){for (i = 0; i < w - x; i++){for (j = -y; j < h; j++){CvInvoke.cvSet2D(dst, j + y, i + x, CvInvoke.cvGet2D(src, j, i));}}}else if (x < 0 && y >= 0){for (i = -x; i < w; i++){for (j = 0; j < h - y; j++){CvInvoke.cvSet2D(dst, j + y, i + x, CvInvoke.cvGet2D(src, j, i));}}}else{for (i = -x; i < w; i++){for (j = -y; j < h; j++){CvInvoke.cvSet2D(dst, j + y, i + x, CvInvoke.cvGet2D(src, j, i));}}}return OpenCVEmguCVDotNet.IplImagePointerToEmgucvImage<Bgr, Byte>(dst);}}}using System;using System.Drawing;using System.Drawing.Imaging;using System.Runtime.InteropServices;using Emgu.CV;using Emgu.CV.CvEnum;namespace ZNLGIS{public class OpenCVEmguCVDotNet{/// <summary>/// 将MIplImage结构转换到IplImage指针;/// 注意:指针在使⽤完之后必须⽤Marshal.FreeHGlobal⽅法释放。

CC++BMP(24位真彩色)图像处理(2)------图像截取

CC++BMP(24位真彩色)图像处理(2)------图像截取

CC++BMP(24位真彩⾊)图像处理(2)------图像截取对上⼀篇博客《C/C++ BMP(24位真彩⾊)图像处理(1)------图像打开与数据区处理》的代码做⼩部分的修改,就可以进⾏BMP图像的截取操作,代码如下:#include <string.h>#include <math.h>#include <stdio.h>#include <stdlib.h>#include <malloc.h>#include<time.h>//时间相关头⽂件,可⽤其中函数计算图像处理速度#define WIDTHBYTES(bits) (((bits)+31)/32*4)//⽤于使图像宽度所占字节数为4byte的倍数#define MYCUT_HEIGHT 100 //截取⾼度#define MYCUT_WIDTH 100 //截取宽度#define BEGIN_X 0 //截取位图开始位置X坐标#define BEGIN_Y 0 //截取位图开始位置Y坐标typedef unsigned char BYTE;typedef unsigned short WORD;typedef unsigned long DWORD;typedef long LONG;//位图⽂件头信息结构定义//其中不包含⽂件类型信息(由于结构体的内存结构决定,要是加了的话将不能正确读取⽂件信息)typedef struct tagBITMAPFILEHEADER {DWORD bfSize; //⽂件⼤⼩WORD bfReserved1; //保留字,不考虑WORD bfReserved2; //保留字,同上DWORD bfOffBits; //实际位图数据的偏移字节数,即前三个部分长度之和} BITMAPFILEHEADER;//信息头BITMAPINFOHEADER,也是⼀个结构,其定义如下:typedef struct tagBITMAPINFOHEADER{//public:DWORD biSize; //指定此结构体的长度,为40LONG biWidth; //位图宽LONG biHeight; //位图⾼WORD biPlanes; //平⾯数,为1WORD biBitCount; //采⽤颜⾊位数,可以是1,2,4,8,16,24,新的可以是32DWORD biCompression; //压缩⽅式,可以是0,1,2,其中0表⽰不压缩DWORD biSizeImage; //实际位图数据占⽤的字节数LONG biXPelsPerMeter; //X⽅向分辨率LONG biYPelsPerMeter; //Y⽅向分辨率DWORD biClrUsed; //使⽤的颜⾊数,如果为0,则表⽰默认值(2^颜⾊位数)DWORD biClrImportant; //重要颜⾊数,如果为0,则表⽰所有颜⾊都是重要的} BITMAPINFOHEADER;void main(){long now=0;now=clock();//存储图像处理开始时间BITMAPFILEHEADER bitHead,writebitHead;BITMAPINFOHEADER bitInfoHead,writebitInfoHead;FILE* pfile;//输⼊⽂件FILE* wfile;//输出⽂件char strFile[50]="E:\\testpicture\\1.bmp";//打开图像路径,BMP图像必须为24位真彩⾊格式char strFilesave[50]="E:\\testpicture\\2.bmp";//处理后图像存储路径pfile = fopen(strFile,"rb");//⽂件打开图像wfile = fopen(strFilesave,"wb");//打开⽂件为存储修改后图像做准备//读取位图⽂件头信息WORD fileType;fread(&fileType,1,sizeof(WORD),pfile);fwrite(&fileType,1,sizeof(WORD),wfile);if(fileType != 0x4d42){printf("file is not .bmp file!");return;}//读取位图⽂件头信息fread(&bitHead,1,sizeof(tagBITMAPFILEHEADER),pfile);writebitHead=bitHead;//由于截取图像头和源⽂件头相似,所以先将源⽂件头数据赋予截取⽂件头//读取位图信息头信息fread(&bitInfoHead,1,sizeof(BITMAPINFOHEADER),pfile);writebitInfoHead=bitInfoHead;//同位图⽂件头相似writebitInfoHead.biHeight=MYCUT_HEIGHT;//为截取⽂件重写位图⾼度writebitInfoHead.biWidth=MYCUT_WIDTH;//为截取⽂件重写位图宽度int mywritewidth=WIDTHBYTES(writebitInfoHead.biWidth*writebitInfoHead.biBitCount);//BMP图像实际位图数据区的宽度为4byte的倍数,在此计算实际数据区宽度 writebitInfoHead.biSizeImage=mywritewidth*writebitInfoHead.biHeight;//计算位图实际数据区⼤⼩writebitHead.bfSize=54+writebitInfoHead.biSizeImage;//位图⽂件头⼤⼩为位图数据区⼤⼩加上54bytefwrite(&writebitHead,1,sizeof(tagBITMAPFILEHEADER),wfile);//写回位图⽂件头信息到输出⽂件fwrite(&writebitInfoHead,1,sizeof(BITMAPINFOHEADER),wfile);//写回位图信息头信息到输出⽂件int width = bitInfoHead.biWidth;int height = bitInfoHead.biHeight;//分配内存空间把源图存⼊内存int l_width = WIDTHBYTES(width*bitInfoHead.biBitCount);//计算位图的实际宽度并确保它为4byte的倍数int write_width = WIDTHBYTES(writebitInfoHead.biWidth*writebitInfoHead.biBitCount);//计算写位图的实际宽度并确保它为4byte的倍数BYTE *pColorData=(BYTE *)malloc(height*l_width);//开辟内存空间存储图像数据memset(pColorData,0,height*l_width);BYTE *pColorDataMid=(BYTE *)malloc(mywritewidth*MYCUT_HEIGHT);//开辟内存空间存储图像处理之后数据memset(pColorDataMid,0,mywritewidth*MYCUT_HEIGHT);long nData = height*l_width;long write_nData = mywritewidth*MYCUT_HEIGHT;//截取的位图数据区长度定义//把位图数据信息读到数组⾥fread(pColorData,1,nData,pfile);//图像处理可通过操作这部分数据加以实现//截取图像数据区操作,在操作过程中注意截取图像是否越界,可在此处加⼊代码进⾏越界处理for(int hnum=height-BEGIN_Y-MYCUT_HEIGHT;hnum<height-BEGIN_Y;hnum++)//由于BMP图像的数据存储格式起点是图像的左下⾓,所以需要进⾏坐标换算操作 for(int wnum=BEGIN_X;wnum<BEGIN_X+MYCUT_WIDTH;wnum++){int pixel_point=hnum*l_width+wnum*3;//数组位置偏移量,对应于图像的各像素点RGB的起点int write_pixel_point=(hnum-height+BEGIN_Y+MYCUT_HEIGHT)*mywritewidth+(wnum-BEGIN_X)*3;pColorDataMid[write_pixel_point]=pColorData[pixel_point];pColorDataMid[write_pixel_point+1]=pColorData[pixel_point+1];pColorDataMid[write_pixel_point+2]=pColorData[pixel_point+2];}fwrite(pColorDataMid,1,write_nData,wfile); //将处理完图像数据区写回⽂件fclose(pfile);fclose(wfile);printf("图像处理完成\n");printf("运⾏时间为:%dms\n",int(((double)(clock()-now))/CLOCKS_PER_SEC*1000));//输出图像处理花费时间信息}。

在VC++6.0中将JPG格式图片转换成BMP格式

在VC++6.0中将JPG格式图片转换成BMP格式

在VC++6.0中将JPG格式图片转换成BMP格式思路:利用GDI+来完成难点:(1)配置GDI开发环境,添加配置代码(2)在当文档程序中添加转换代码注意:本文档由ybdesire参考网上资料撰写完成,代码已经做过测试,可直接复制张贴实现过程:一、配置GDI开发环境(1)下载GDI+ SDK for Visual C++ 6.0/code/legacy/gdi/GDIPlus.zip下载的GDIPlus文件夹中有Includes,Lib文件夹和gdiplus.dll文件。

将Includes和Lib中的文件分别拷到VC6安装目录中的VC98\include和lib文件夹中;新建MFC项目后,才使用gdiplus.dll,到时候将它拷到对应工程的debug 文件夹下。

(2)新建MFC单文档应用程序show:1、在StdAfx.h 中添加如下代码#include <afxdtctl.h>#define ULONG_PTR ULONG#include <gdiplus.h>using namespace Gdiplus;#pragma comment(lib, "gdiplus.lib")2、如(1)中所说,将gdiplus.dll拷贝到本工程的Debug或Release目录下3、在show.h中的class CShowApp : public CWinApp中添加private:GdiplusStartupInput m_gdiplusStartupInput;ULONG_PTR m_pGdiToken;4、在show.cpp中的BOOL CShowApp::InitInstance()中添加GdiplusStartup(&m_pGdiToken,&m_gdiplusStartupInput,NULL);5、为CShow App添加名字为ExitInstance的虚函数的,并在ExitInstance中添加如下退出GDI+的代码GdiplusShutdown(m_pGdiToken);return CWinApp::ExitInstance();(3)测试GDI+是否配置成功void CShowView::OnDraw(CDC* pDC){CShowDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);Graphics graphics(pDC->m_hDC);Pen pen(Color(255, 0, 255));graphics.DrawLine(&pen, 0, 0, 200, 100);}若能成功运行,表明GDI+配置成功二、添加转换代码,实现将打开的JPG格式文件保存成BMP格式文件(1)在CSshowView中添加如下成员变量CString strOpenFileName;(2)在CSshowView中添加如下成员函数1、在CSshowView中添加ToWChar函数WCHAR* CShowView::ToWChar(char *str){//在GDI+中,有关字符的参数类型全部都是WCHAR类型的//该函数是将传统字符串进行转换static WCHAR buffer[1024];wcsset(buffer,0);MultiByteToWideChar(CP_ACP,0,str,strlen(str),buffer,1024);return buffer;}2、在CSshowView中添加GetImageCLSID函数int CShowView::GetImageCLSID(const WCHAR *format, CLSID *pCLSID) {UINT num=0;UINT size=0;ImageCodecInfo* pImageCodecInfo=NULL;GetImageEncodersSize(&num,&size);if(size==0)return FALSE; // 编码信息不可用// 分配内存pImageCodecInfo=(ImageCodecInfo*)(malloc(size));if(pImageCodecInfo==NULL)return FALSE; // 分配失败// 获得系统中可用的编码方式的所有信息GetImageEncoders(num,size,pImageCodecInfo);// 在可用编码信息中查找 format 格式是否被支持for(UINT i=0;i<num;++i){//MimeType: 编码方式的具体描述if (wcscmp(pImageCodecInfo[ i] .MimeType,format)==0){*pCLSID=pImageCodecInfo[i].Clsid;free(pImageCodecInfo);return TRUE;}}free(pImageCodecInfo);return FALSE;}3、在MFC ClassWixard中重载OnFileOpen()void CShowView::OnFileOpen(){static char szFilter[ ]="常见图像格式文件(*.*)|*.*|";CFileDialogdlgChoseImage(1,NULL,NULL,NULL,szFilter);if(dlgChoseImage.DoModal() ==IDOK){strOpenFileName=dlgChoseImage.GetPathName();// 打开文件后立即在窗口中显示 (重绘客户窗口)this->Invalidate() ;}}4、在MFC ClassWixard中重载OnFileSave()void CShowView::OnFileSave(){if( strOpenFileName.IsEmpty() ){AfxMessageBox("当前没有打开图像文件, 不能进行保存!");return;}// 建立图形对象Graphics graphics(GetDC()->m_hDC);// 装入当前已经打开的图像文件Imageimage(ToWChar(strOpenFileName.GetBuffer(strOpenFileName.GetLength() ) ));CString strFileSave;// 将其他格式的图像全部另存为 BMP 文件static char szFilter[ ]= "位图(*.BMP)|*.BMP|";CFileDialogdlgChoseImage(0,"BMP",strOpenFileName,NULL,szFilter);if(dlgChoseImage.DoModal() ==IDOK){strFileSave=dlgChoseImage.GetPathName();CLSID clsid;if(GetImageCLSID(L"image/bmp", &clsid)){image.Save(ToWChar(strFileSave.GetBuffer(strFileSave.GetLength() )), &clsid, NULL);// 将保存后的图像进行显示strOpenFileName=strFileSave;this->Invalidate() ;}}}参考资料[1]/poonjun/archive/2009/01/04/3701724.aspx[2]/DavidHu/articles/1191635.html[3]/bbsgcon.php?board=VisualC&num=785[4]《图像格式转换在数字仪表识别系统中的应用》刘娜, 汪仁煌, 庞然/*-------------------------------------------------------------*/扩展知识阅读[3] 色彩鲜艳漂亮的高品质图像,一个个形象的Windows图标,高速运动、活灵活现的三维动画,这些生动的图形无一不显示着程序设计者的艺术才华。

VC++实现图像二值处理

VC++实现图像二值处理

Visual C++实现二值图像处理二值图像是一种简单的图像格式,它只有两个灰度级,即"0"表示黑色的像素点,"255"表示白色的像素点,至于如何从一幅普通的图像获得二值图像,请参考我近期在天极网上发表的《Visual C++编程实现图像的分割》一文。

二值图像处理在图像处理领域占据很重要的位置,在具体的图像处理应用系统中,往往需要对于获得的二值图像再进一步进行处理,以有利于后期的识别工作。

二值图像处理运算是从数学形态学下的集合论方法发展起来的,尽管它的基本运算很简单,但是却可以产生复杂的效果。

常用的二值图像处理操作有许多方法,如腐蚀、膨胀、细化、开运算和闭运算等等。

本文对这些内容作些研究探讨,希望对爱好图像处理的朋友有所帮助。

一、腐蚀和膨胀形态学是一门新兴科学,它的用途主要是获取物体拓扑和结果信息,它通过物体和结构元素相互作用的某些运算,得到物体更本质的形态。

它在图像处理中的应用主要是:b5E2RGbCAP1.利用形态学的基本运算,对图像进行观察和处理,从而达到改善图像质量的目的;2.描述和定义图像的各种几何参数和特征,如面积,周长,连通度,颗粒度,骨架和方向性。

限于篇幅,我们只介绍简单二值图像的形态学运算,对于灰度图像的形态学运算,有兴趣的读者可以看有关的参考书。

二值图像基本的形态学运算是腐蚀和膨胀,简单的腐蚀是消除物体的所有边界点的一种过程,其结果是使剩下的物体沿其周边比原物体小一个像素的面积。

如果物体是圆的,它的直径在每次腐蚀后将减少两个像素,如果物体在某一点处任意方向上连通的像素小于三个,那么该物体经过一次腐蚀后将在该点处分裂为二个物体。

简单的膨胀运算是将与某物体接触的所有背景点合并到该物体中的过程。

过程的结果是使物体的面积增大了相应数量的点,如果物体是圆的,它的直径在每次膨胀后将增大两个像素。

如果两个物体在某一点的任意方向相隔少于三个像素,它们将在该点连通起来。

Visual+C++实现数字图像增强处理

Visual+C++实现数字图像增强处理

前言对于一个图像处理系统来说,可以将流程分为三个阶段,在获取原始图像后,首先是图像预处理阶段、第二是特征抽取阶段、第三是识别分析阶段。

图像预处理阶段尤为重要,如果这阶段处理不好,后面的工作根本无法展开。

在实际应用中,我们的系统获取的原始图像不是完美的,例如对于系统获取的原始图像,由于噪声、光照等原因,图像的质量不高,所以需要进行预处理,以有利于提取我们感兴趣的信息。

图像的预处理包括图像增强、平滑滤波、锐化等内容。

图像的预处理既可以在空间域实现,也可以在频域内实现,我们主要介绍在空间域内对图像进行点运算,它是一种既简单又重要的图像处理技术,它能让用户改变图像上像素点的灰度值,这样通过点运算处理将产生一幅新图像。

下面我们开始介绍与图像点运算的相关知识。

一、图像的直方图图像直方图是图像处理中一种十分重要的图像分析工具,它描述了一幅图像的灰度级内容,任何一幅图像的直方图都包含了丰富的信息,它主要用在图象分割,图像灰度变换等处理过程中。

从数学上来说图像直方图是图像各灰度值统计特性与图像灰度值的函数,它统计一幅图像中各个灰度级出现的次数或概率;从图形上来说,它是一个二维图,横坐标表示图像中各个像素点的灰度级,纵坐标为各个灰度级上图像各个像素点出现的次数或概率。

如果不特别说明,本讲座中的直方图的纵坐标都对应着该灰度级在图像中出现的概率。

我们的例子是在一个对话框中显示一个图像的直方图,为实现该目的,我们定义了一个名为"ZFT"的对话框类用来显示图像的直方图,具体实现代码和效果图如下(关于代码实现部分可以参考笔者2001年在天极网上发表的一篇VC实现数字图像处理的文章)://////////////////////////////////直方图对话框构造函数;ZFT::ZFT(CWnd* pParent /*=NULL*/): CDialog(ZFT::IDD, pParent)//ZFT为定义的用来显示直方图的对话框类;{Width=Height=0;//对话框初始化阶段设置图像的宽和高为"0";}////////////////////////对话框重画函数;void ZFT::OnPaint(){CRect rect;//矩形区域对象;CWnd *pWnd;//得到图片框的窗口指针;pWnd=GetDlgItem(IDC_Graphic);//得到ZFT对话框内的"Frame"控件的指针;file://(IDC_Graphic为放置在对话框上的一个"Picture"控件,并讲类型设置为"Frame")。

VC++数字图像处理

VC++数字图像处理

Visual C++数字图像处理广义地讲,凡是记录在纸介质上的、拍摄在底片和照片上的、显示在电视、投影仪和计算机屏幕上的所有具有视觉效果的画面都可以称为图像。

根据图像记录方式的不同,图像可分为两大类:一类是模拟图像(Analog Image),另一类是数字图像(Digital Image)。

模拟图像是通过某种物理量(光、电等)的强弱变化来记录图像上各点的亮度信息的,例如模拟电视图像;而数字图像则完全是用数字(即计算机存储的数据)来记录图像亮度信息的。

所谓数字图像处理(Digital Image Processing),就是指用数字计算机及其他相关的数字技术,对数字图像施加某种或某些运算和处理,从而达到某种预期的处理目的。

随着数字技术和数字计算机技术的飞速发展,数字图像处理技术在近 20 多年的时间里,迅速发展成为一门独立的有强大生命力的学科,其应用领域十分广泛。

作为数字图像处理技术的实现环节,本书将在 Visual C++环境下介绍图像各种典型算法的编程实现。

而作为一本书的开始,本章我们将介绍图像编程的基础知识,如数字图像的点阵数据、调色板概念、BMP 文件结构以及设备无关位图(DIB)等,它是后面章节学习的基础。

1.1 图像、颜色表和色彩空间1.1.1 图像组成数字图像的基本单位是像素(Pixel),也就是说,数字图像是像素的集合。

如图 1-1 所示,图中每个格点代表一个像素,该图是一个白色背景下包含灰色矩形的图像。

图 1-1 放大后的矩形图像数字图像通常存放在计算机的外存储器设备中,例如硬盘、光盘等,在需要进行显示和处理时才被调入内存的数组中。

从本质上讲,图像数据在计算机内存或硬盘中是以字符型数据存在的,这与其他整型数据或者浮点型数据没有任何区别,都是一种数字表达符号,当把它在计算机屏幕上显示出来时,才是我们人眼看到的真正有意义的数字图像。

普通的显示器屏幕也是由许多点(像素)构成的,显示时,电子枪每次从左到右、从上到下进行扫描,为每个像素着色,利用人眼的视觉暂留效应就可以显示出一屏完整的图像。

Cimage类处理图像像素(数据)的3种方式(转)

Cimage类处理图像像素(数据)的3种方式(转)

Cimage类处理图像像素(数据)的3种⽅式(转)这⾥只讨论对图像像素的处理,cimage类的具体⽤法查相关资料#include <atlimage.h> //VS2010以后不⽤加这个……………………CImage m_Image; //或CImage* m_Image; 下⾯例⼦程序我⽤的CImage m_Image; 只是⼀个⽤成员选择符,⼀个⽤指针操作,效率上可能有所差异下⾯是3种⽅法:⼀、⽤Cimage类的成员函数进⾏处理这⾥假设你已经加载了图像位图,并与CImage对象m_Image相关联。

相关成员函数主要有:GetPixel 返回像素颜⾊SetPixel 设置像素颜⾊如:m_Image.SetPixel( i-1, j-1, RGB(rr,gg,bb));SetPixelRGB 设置像素的红绿蓝如:m_Image.SetPixelRGB(x,y,avg,avg,avg);SetColorTable 设置调⾊板颜⾊分量(红、绿、蓝)值GetWidth 宽度(以像素为单位)GetHeight ⾼度1、程序⽰例1)⼀个双线性插值放⼤程序。

[cpp]1. if (m_Image.IsNull())2. return;3. // 创建对话框4. DlgInterpolation TranPara;5. //显⽰对话框,提⽰⽤户设定量6. if (TranPara.DoModal() != IDOK)7. return;8. int k=TranPara.m_inter;9. BeginWaitCursor();10. CImage m_Image1;11. if (! m_Image1.IsNull())12. {13. m_Image1.Destroy();14. }15. m_Image1.Create( m_Image.GetWidth()*k, m_Image.GetHeight()*k, 24,0);16. // 四个最临近象素的坐标17. int x1, x2;18. int y1, y2;19. // 四个最临近象素值20. unsigned char f1, f2, f3, f4;21. // ⼆个插值中间值22. unsigned char f12, f34;23. //计算结果24. int fr,fb,fg;25. double epsilon = 0.001;26. COLORREF pixel11,pixel12,pixel21,pixel22;27. int nHeight1 = m_Image1.GetHeight();28. int nWidth1 = m_Image1.GetWidth();29. int nHeight = m_Image.GetHeight();30. int nWidth = m_Image.GetWidth();31. double m=((double)nWidth1-1)/((double)nWidth-1);32. for (int i=0; i<nWidth1; i++)33. {34. for (int j=0; j<nHeight1; j++)35. {36. double x=double((double)i/m);37. double y=double((double)j/m);38. //计算四个最临近象素的坐标,+1向右下⽅移动39. x1 = (int) x;40. x2 = x1 + 1;41. y1 = (int) y;42. y2 = y1 + 1;43. if( (x < 0) || (x > nWidth - 1) || (y < 0) || (y > nHeight - 1))44. {45. //要计算的点不在源图范围内,返回-146. continue;47. }48. else49. {50. if (fabs(x - nWidth + 1) <= epsilon )51. {52. // 要计算的点在图像右边缘上53. if (fabs(y -nHeight + 1) <= epsilon)54. {55. // 要计算的点正好是图像最右下⾓那⼀个象素,直接返回该点象素值56. pixel11 = m_Image.GetPixel(x1,y1);57. f1 = (unsigned char)GetRValue(pixel11);58. fr=(int)f1;59. f1 = (unsigned char)GetGValue(pixel11);60. fg=(int)f1;61. f1 = (unsigned char)GetBValue(pixel11);62. fb=(int)f1;63. }64. else65. {66. // 在图像右边缘上且不是最后⼀点,直接⼀次插值即可67. pixel11 = m_Image.GetPixel(x1,y1);68. pixel12 = m_Image.GetPixel(x1,y2);69. f1 = (unsigned char)GetRValue(pixel11);70. f3 = (unsigned char)GetRValue(pixel12);71. fr= (int) (f1 + (y -y1) * (f3 - f1));72. f1 = (unsigned char)GetGValue(pixel11);73. f3 = (unsigned char)GetGValue(pixel12);74. fg= (int) (f1 + (y -y1) * (f3 - f1));75. f1 = (unsigned char)GetBValue(pixel11);76. f3 = (unsigned char)GetBValue(pixel12);77. fb= (int) (f1 + (y -y1) * (f3 - f1));78. }79. }80. else if (fabs(y - nHeight + 1) <= epsilon)81. {82. // 要计算的点在图像下边缘上且不是最后⼀点,直接⼀次插值即可83. pixel11 = m_Image.GetPixel(x1,y1);84. pixel21 = m_Image.GetPixel(x2,y1);85. f1 = (unsigned char)GetRValue(pixel11);86. f2 = (unsigned char)GetRValue(pixel21);87. fr=(int) (f1 + (x -x1) * (f2 - f1));88. f1 = (unsigned char)GetGValue(pixel11);89. f2 = (unsigned char)GetGValue(pixel21);90. fg=(int) (f1 + (x -x1) * (f2 - f1));91. f1 = (unsigned char)GetBValue(pixel11);92. f2 = (unsigned char)GetBValue(pixel21);93. fb=(int) (f1 + (x -x1) * (f2 - f1));94. }95. else96. {97. pixel11 = m_Image.GetPixel(x1,y1);98. pixel12 = m_Image.GetPixel(x1,y2);99. pixel21 = m_Image.GetPixel(x2,y1);100. pixel22 = m_Image.GetPixel(x2,y2);101. // 计算四个最临近象素值102. f1 = (unsigned char)GetRValue(pixel11);103. f2 = (unsigned char)GetRValue(pixel21);104. f3 = (unsigned char)GetRValue(pixel12);105. f4 = (unsigned char)GetRValue(pixel22);106. f12 = (unsigned char) (f1 + (x - x1) * (f2 - f1));107. f34 = (unsigned char) (f3 + (x - x1) * (f4 - f3));108. fr= (int) (f12 + (y -y1) * (f34 - f12));109. f1 = (unsigned char)GetGValue(pixel11);110. f2 = (unsigned char)GetGValue(pixel21);111. f3 = (unsigned char)GetGValue(pixel12);112. f4 = (unsigned char)GetGValue(pixel22);113. f12 = (unsigned char) (f1 + (x - x1) * (f2 - f1));114. f34 = (unsigned char) (f3 + (x - x1) * (f4 - f3));115. fg= (int) (f12 + (y -y1) * (f34 - f12));116. f1 = (unsigned char)GetBValue(pixel11);117. f2 = (unsigned char)GetBValue(pixel21);118. f3 = (unsigned char)GetBValue(pixel12);119. f4 = (unsigned char)GetBValue(pixel22);120. f12 = (unsigned char) (f1 + (x - x1) * (f2 - f1));121. f34 = (unsigned char) (f3 + (x - x1) * (f4 - f3));122. fb= (int) (f12 + (y -y1) * (f34 - f12));123. }124. }125. m_Image1.SetPixel(i,j, RGB(fr,fg,fb));126. }127. }128. m_Image.Destroy();129. m_Image.Create( m_Image1.GetWidth(), m_Image1.GetHeight(), 24, 0);130. COLORREF pixel;131. for (int i=0; i<nWidth1; i++)132. {133. for (int j=0; j<nHeight1; j++)134. {135. pixel = m_Image1.GetPixel(i,j);136. int y=GetRValue(pixel);137. int p=GetGValue(pixel);138. int b=GetBValue(pixel);139. m_Image.SetPixelRGB(i,j,GetRValue(pixel),GetGValue(pixel),GetBValue(pixel));140. }141. }142. m_Image1.Destroy();143. Invalidate();144. EndWaitCursor();2)处理视频帧[cpp]1. ……2. Defog(imageprosses, nimgWidth, nimgheigt);/*我加的⼀个雾天图像增强的动态库,imageprosses是视频的⼀帧,输⼊imageprosses处理,并输出imageprosses*/3. int rr = 0, gg = 0, bb = 0;4. for (int i = 0; i < nimgWidth; i++)5. {6. for (int j = 1; j <= nimgheigt; j++)7. {8. bb=(int)imageprosses[3*i*j];9. gg=(int)imageprosses[3*i*j+1];10. rr=(int)imageprosses[3*i*j+2];11. m_Image.SetPixel(i, j-1, RGB(rr,gg,bb));/*设置⼀帧图像的像素值⽤来显⽰*/12. }13. }14. ……2、⽐较:⾮常慢。

(转)C#进行图像处理的几种方法(Bitmap,BitmapData,IntPtr)

(转)C#进行图像处理的几种方法(Bitmap,BitmapData,IntPtr)

(转)C#进⾏图像处理的⼏种⽅法(Bitmap,BitmapData,IntPtr)转⾃C#进⾏图像处理的⼏种⽅法本⽂讨论了C#图像处理中Bitmap类、BitmapData类和unsafe代码的使⽤以及字节对齐问题。

Bitmap类命名空间:System.Drawing封装 GDI+ 位图,此位图由图形图像及其属性的像素数据组成。

Bitmap 是⽤于处理由像素数据定义的图像的对象。

利⽤C#类进⾏图像处理,最⽅便的是使⽤Bitmap类,使⽤该类的GetPixel()与SetPixel()来访问图像的每个像素点。

下⾯是MSDN中的⽰例代码:public void GetPixel_Example(PaintEventArgs e){// Create a Bitmap object from an image file.Bitmap myBitmap = new Bitmap("Grapes.jpg");// Get the color of a pixel within myBitmap.Color pixelColor = myBitmap.GetPixel(50, 50);// Fill a rectangle with pixelColor.SolidBrush pixelBrush = new SolidBrush(pixelColor);e.Graphics.FillRectangle(pixelBrush, 0, 0, 100, 100);}可见,Bitmap类使⽤⼀种优雅的⽅式来操作图像,但是带来的性能的降低却是不可忽略的。

⽐如对⼀个800*600的彩⾊图像灰度化,其耗费的时间都要以秒为单位来计算。

在实际项⽬中进⾏图像处理,这种速度是决对不可忍受的。

BitmapData类命名空间:System.Drawing.Imaging指定位图图像的属性。

BitmapData 类由 Bitmap 类的 LockBits 和 UnlockBits ⽅法使⽤。

Visual C++数字图像处理典型案例详解

Visual C++数字图像处理典型案例详解

第1章 数字图像处理软件开发概述“心有多大,舞台就有多大。

”开发数字图像处理软件,需要想象力,而要把想象变成现实,则需要得心应手的开发平台。

目前常用于开发数字图像处理软件的平台可以粗略地分为通用平台和专用平台两大类。

通用平台不是专门针对数字图像处理软件开发而打造的,但是却可以用于开发数字图像处理系统,如Visual C++、Matlab等。

为了提高开发效率,通用平台往往结合专门的软件包(如OpenCV、VTK 等)或工具箱(如Matlab中的Image Processing工具箱等)进行数字图像处理软件开发。

专用平台则是专为数字图像处理或更进一步的机器视觉系统开发量身定制的,这类开发平台中均内置了大量专门用于数字图像处理的数据结构、对象、函数或组件模块,可供开发人员方便地调用,在更高的层次上进行数字图像处理系统的开发,如Halcon、VisionPro等。

本章主要介绍本书将要用到的几种开发平台及其配置和使用方法。

本章要点Visual C++处理数字图像的基本方法在Visual C++中使用OpenCV在Visual C++中使用VTK1.1 Visual C++“工欲善其事,必先利其器。

”Visual C++便是众多开发工具中的“一把所向披靡的利器”。

Visual C++(简称VC)是Microsoft公司的Visual Studio开发工具箱中的一个C++程序开发环境。

自诞生以来,凭借着C++语言的强大威力、开发环境的良好支持,以及与Windows操作系统的“血缘”关系,一直是Windows操作系统环境下最主要的开发工具之一。

使用VC可以完成各种各样应用程序的开发,从底层软件到上层直接面向用户的软件,而且用VC开发出的产品与Windows操作系统最具“亲和力”。

掌握了VC,就等于进入了Windows编程的自由王国。

VC在数字图像处理软件开发中也占据着极其重要的地位。

第1章Visual C++1.1.1 Visual C++概述VC是一个面向对象的可视化集成开发系统,它不但具有程序框架自动生成、灵活方便的类管理、代码编写和界面设计集成交互操作、可开发多种程序等优点,而且通过简单的设置就可使其生成的程序框架支持数据库接口、OLE2、WinSock网络、3D控制界面。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

delete pData; pData=NULL;
if(m_pBMI!=NULL) delete m_pBMI; m_pBMI=NULL; if(pfi!=NULL)
delete pfi; pfi=NULL; } CAvi::CAviCreate(CString &string)//读文件初始化该类 { HRESULT hr; pfi=new AVIFILEINFO; hr = AVIFileOpen(&pfile, // returned file pointer string, // file name OF_READ, // mode to open file with NULL); hr= AVIFileInfo(pfile, file://获取 AVI 信息,放入 pfi 中 pfi, sizeof(AVIFILEINFO) ); cx=pfi­>dwWidth;//图象宽、高 cy=pfi­>dwHeight; hr=AVIFileGetStream(//将 AVI 变成视频流 pfile, &pavi, streamtypeVIDEO, 0//LONG lParam ); m_pBMI=new BITMAPINFO;//定义 BMP 信息头 m_pBMI­>bmiHeader.biBitCount=24; m_pBMI­>bmiHeader.biClrImportant=0; m_pBMI­>bmiHeader.biClrUsed=0; m_pBMI­>bmiHeader.biCompression=BI_RGB; m_pBMI­>bmiHeader.biHeight=cy; m_pBMI­>bmiHeader.biWidth=cx; m_pBMI­>bmiHeader.biPlanes=1; m_pBMI­>bmiHeader.biSize=sizeof(BITMAPINFOHEADER); m_pBMI­>bmiHeader.biXPelsPerMeter=0; m_pBMI­>bmiHeader.biYPelsPerMeter=0; m_pBMI­>bmiHeader.biSizeImage=cx*cy*3; pData=(BYTE*)new char[cx*cy*3];//根据 AVI 中 BMP 图象的信息定义缓冲区 } BOOL CAvi::AviRead(int mFrame)//将 AVI 文件的 M 帧数据读入 PData 缓冲区 { HRESULT hr; hr= AVIStreamRead( pavi, mFrame, 1, pData, cx*cy*3,
class CimageData : public CDaoRecordset { public: CimageData (CDaoDatabase* pDatabase =
NULL); DECLARE_DYNAMIC(CimageData) file://{{AFX_FIELD(CimageData, CDaoRecordset) CByteArray m_Images;// 声 明 字 节 数 组 用 来 存 放 图 像 数 据 file://}}AFX_FIELD // Overrides //
nColors=bmiHeader.biClrUsed ? bmiHeader.biClrUsed : 1 << bmiHeader.biBitCount; file://确定图像
的颜色数
}
void
CimageData::DoFieldExchange(CDaoFieldExchange*
pFX)
{ file://{{AFX_FIELD_MAP(CimageData) pFX­>SetFieldType(CDaoFieldExchange::outputColumn); DFX_Binary(pFX, _T("[Images]"), m_Images);//以二进制方式在 Images 字段和 m_Images 变量间
file://}}AFX_FIELD_INIT m_nDefaultType = dbOpenDynaset;// 以 动 态 集 方 式 打 开 数 据 库 }
CString CimageData::GetDefaultDBName() { return _T("E:\\IMAGES.mdb");//默认的 ACESS 数据 库在 E 盘,名为 IMAGES } CString CimageData::GetDefaultSQL() { return _T("[Table]");//默认打开数据库中名为"Table"的表
利用 Visual C++实现 AVI 文件的图像截取 AVI 文件就是我们所说的多媒体文件,所谓的 AVI 图像就是视频图像,该文件是一个 RIFF 说 明文件,它用于获取、编辑、演示音频、视频序列。一般的 AVI 文件包含音频流和视频流,有 的特殊的 AVI 还包含一个控制路径或 MIDI 路径作为附加的数据流。
DoFieldExchange(CDaoFieldExchange* pFX); file://}}AFX_VIRTUAL 该类的实现为:
CimageData::
CimageData
(CDaoDatabase*
pdb)
:
CDaoRecordset(pdb)
{ file://{{AFX_FIELD_INIT(CimageData) m_nFields = 1;// 数 据 库 的 表 中 仅 有 一 个 字 段
NULL, NULL ); if(hr==0) return TRUE; else return FALSE; }
上述 Cavi 类实现部分所涉及到的 API 函数可以参考微软提供的 MSDN。Cavi 类中的 pData 缓冲区存放 AVI 文件中的具体某一帧图像数据,同时 Cavi 类的 m_pBMI 为 BMP 图像文件信息 结构,这时可以根据图像的大小定义 BMP 图像文件头结构,关于 BMP 文件的存储,由于篇幅 的原因,我不在多讲了,有兴趣的读者可以参见笔者的拙作"Visual C++6.0 开发灰度位图处理" ( 天 极 网 软 件 栏 目 2001.9.10 发 表 ), 该 文 里 面 讲 述 了 如 何 存 取 BMP 文 件 。 以 上 程 序 在 Windows2000、Visual C++6.0 环境下顺利编译通过,运行正常。
Hale Waihona Puke Visual C++中实现对图像数据的读取显示 在利用 VC 进行数据库编程时,经常需要处理数据库中的图像数据,将该图像从数据库中读取 出来并显示,图像数据与文本字段不同,它是作为 OLE 字段在数据库中存储,通过数据集对象
的成员变量自动交换得到的图像数据,得到的数据并不能直接显示,如何处理图像数据,一直
据库,读取的图像数据显示在一个对话框上,至于使用 ODBC、DAO 还是 ADO,这要根据具
体情况而定,但无论使用哪一种,对图像的显示来说,实现的过程是大同小异的。由于篇幅有
限,文章中对如何实现数据库的连接不再作具体的说明,有兴趣的读者朋友可以参考 VC 数据 库编程的资料。实现过程中,首先定义一个 CDaoRecordset 的子类 CimageData 如下:
在使用 API 函数操作 AVI 文件时,一定要注意用 AVIFileInit()来初始化 AVI 库,程序结束时 用 AVIFileExit()释放 AVI 库,否则 API 函数无法使用。现以操作包含真彩色图像的 AVI 文件为 例,给出 Cavi 类的部分函数的具体实现,其中 CaviCreate()函数用于读取 AVI 文件信息并初始 化 Cavi 类的成员,例如根据 AVI 文件信息定义每帧图像的宽、高、每帧图像的信息头结构等等; 函数 AviRead(int mFrame)用于从 AVI 文件中读取第 mFrame 帧。实现代码显示如下:
交换数据 file://}}AFX_FIELD_MAP }
有了该类,就可以定义相应的对象来与数据库中的图像字段交换数据,下面定义的函数
GetImageData()说明了如何根据读取的 OLE 字段数据生成待显示的图像,需要注意的是该函数
中使用的 CBitmap 类的变量 Bitmap 是预定义的一个全局变量:
是数据库编程中的一个难点,目前关于 VC 进行数据库编程的资料不少,但很少涉及图像数据
的操作,笔者针对一现状,结合自己开发的一个项目,解决了如何显示数据库中的图像这一问
题,本文以操作 ACESS 数据库为例子,讲解一下自己的实现思路,希望对爱好 VC 编程的朋友
们有所帮助,以起到抛砖引玉的作用。
为了简化问题,该数据库的表中只有一个名为 Images 的 OLE 字段,我使用 DAO 连接操作数
现在播放 AVI 文件的软件很多,但大多无法从 AVI 视频文件中读取一帧图像并生成 BMP 格 式的文件。笔者在使用 AVI 文件开发项目过程中对 AVI 文件的操作积累了一些经验,对于如何 实现从 AVI 视频流中获取任意帧的图像数据并存储成 BMP 文件,其中最关键的是要从 AVI 文 件中获取具体某一帧的图像数据,为此我利用 Windows 提供的 API 函数实现了自定义的 CAvi 类,用于操作 AVI 文件。
息 的 起 始 位 置 Array.RemoveAt( 0, HeaderLen ); // 移 动 到 图 像 头 信 息 的 起 始 位 置
BITMAPINFOHEADER &bmiHeader = *(LPBITMAPINFOHEADER)Array.GetData() ; BITMAPINFO &bmInfo = *(LPBITMAPINFO)Array.GetData() ; file://得到图像数据的头信息 int
相关文档
最新文档