VC++图像处理

  • 格式:docx
  • 大小:19.50 KB
  • 文档页数:9

1-1简述图像的bmp位图格式BMP文件由文件头,位图信息头,颜色信息和图像数据四部分组成。

位图文件头结构:BITMAPFILEHEADER位图信息头结构:NITMAPINFOHEADER位图颜色表:RGBQUAD位图样色数据2-1.简述调用调色板的基本方法答:创建一个逻辑调色板需要5步:1.建立一个LOGPALEETTE结构和PALETTEENTRY数组2.对数组元素进行初始化并对成员变量进行设置3.建立Cpalette对象并使用CreatePalette函数初始化调色板对象4.使用SelectPalette函数来将设备描述表和调色板联系起来5.使用CDC中的RealizePalette函数使调色板生效2-2根据图像渐显的实现方法,编程实现图像的渐隐void CDynSplitView2::OnJianxian(){//刷新屏幕CDC *pDC=GetDC();CRect rect(0,0,1000,1000);CBrush brush(RGB(0,0,0));pDC->FillRect(&rect,&brush);//复制图像数据clearmem();CDSplitDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);if(!pDoc ->statedoc&&state2==1 ){BYTE* pBitmapData = CDibNew1->GetData();LPBITMAPINFO pBitmapInfo = CDibNew1->GetInfo();int bitmapHeight= CDibNew1->GetHeight();int bitmapWidth = CDibNew1->GetWidth();if (CDibNew1->GetRGB()) // Has a color table{CPalette * hPalette=CreateBitmapPalette(CDibNew1);CPalette * hOldPalette = pDC->SelectPalette(hPalette, true);pDC->RealizePalette();LPBYTE temp,temp1,temp2;temp=new BYTE[CDibNew1->GetHeight()*CDibNew1->GetWidth()];memset (temp,0,CDibNew1->GetHeight()*CDibNew1->GetWidth());for(int n=256;n>=0;n++){temp1=temp;temp2=pBitmapData;for(int j = 0; j < bitmapHeight; j++){for(int i = 0; i < bitmapWidth; i ++){*temp1=(*temp2)*(n)/256;temp1++;temp2++;}}::StretchDIBits(pDC->GetSafeHdc(),0, 0, bitmapWidth, bitmapHeight, 0, 0, bitmapWidth, bitmapHeight,temp,pBitmapInfo,DIB_RGB_COLORS, SRCCOPY);Sleep(10);}pDC->SelectPalette(hOldPalette, true);::DeleteObject(hPalette);delete temp;}else{LPBYTE temp;temp=new BYTE[CDibNew1->GetHeight()*CDibNew1->GetWidth()*3];memset (temp,0,CDibNew1->GetHeight()*CDibNew1->GetWidth()*3);for(int m=0;m<256;m++){for(int j = 0; j < bitmapHeight; j++){for(int i = 0; i < bitmapWidth; i ++){temp[j*bitmapWidth*3+i*3]=pBitmapData[j*bitmapWidth*3+i*3]*(m)/256; temp[j*bitmapWidth*3+i*3+1]=pBitmapData[j*bitmapWidth*3+i*3+1]*(m)/256;temp[j*bitmapWidth*3+i*3+2]=pBitmapData[j*bitmapWidth*3+i*3+2]*(m)/256;}}::StretchDIBits(pDC->GetSafeHdc(),0, 0, bitmapWidth, bitmapHeight,0, 0, bitmapWidth, bitmapHeight,temp, pBitmapInfo,DIB_RGB_COLORS, SRCCOPY);Sleep(20);}delete temp;}}}2-4.在特效显示中,如何加快或减慢显示速度答:加快就是将代码中的sleep()中的数字改小,相反减慢就是将代码中的sleep()中的数字改大。

3-2.简述图像的镜像变换的基本方法,并编程实现答:1.取得原图的数据区指针2.开辟一个同样大小的缓冲区3.每个像素一次循环。

在原图的像素点的水平坐标变成镜像后的坐标再显示到图像上。

垂直镜像中,则对垂直坐标做相应的处理。

代码:void JiHeBianHuanDib::JingXiang(bool fangshi){// 指向源图像的指针LPBYTE lpSrc;LPBYTE p_data;// 指向要复制区域的指针LPBYTE lpDst;// 指向复制图像的指针LPBYTE temp;// 循环变量LONG i;LONG j;//图像的高与宽long height=this->GetHeight();long wide=this->GetWidth();p_data=this->GetData();// 暂时分配内存,以保存一行图像temp = new BYTE[wide*height];// 判断镜像方式if (fangshi) // 水平镜像{if (m_pBitmapInfoHeader->biBitCount<9) //灰度图像{// 针对图像每行进行操作for(j = 0; j < height; j++){for(i = 0; i < wide;i++){lpSrc = (LPBYTE)p_data +wide *j + i;lpDst = (LPBYTE)temp + wide* j+ wide - i;*lpDst = *lpSrc;}}memcpy(p_data,temp, wide*height);}else //24位彩色{wide=this->GetDibWidthBytes();temp=new BYTE[height*wide];// 针对图像每行进行操作for(j = 0; j < height; j++){for(i = 0; i < wide;i=i+3){lpSrc = (LPBYTE)(p_data +wide *j + i);lpDst = (LPBYTE)temp + wide* j+ wide - i;*(lpDst) = *lpSrc;*(lpDst+1) = *(lpSrc+1);*(lpDst+2) = *(lpSrc+2);}}memcpy(p_data,temp, wide*height);}}else // 垂直镜像{if (m_pBitmapInfoHeader->biBitCount<9) //灰度图像{// 针对上半图像进行操作for(i = 0; i < wide;i++){for(j = 0; j < height; j++){lpSrc = (LPBYTE)p_data + wide * j+i;lpDst = (LPBYTE)temp + wide * (height - j - 1)+i;*lpDst = *lpSrc;}}memcpy(p_data,temp, wide*height);}else //24位彩色{wide=this->GetDibWidthBytes();temp=new BYTE[height*wide];// 针对上半图像进行操作for(i = 0; i < wide;i++){for(j = 0; j < height; j++){lpSrc = (LPBYTE)p_data + wide * j+i;lpDst = (LPBYTE)temp + wide * (height - j - 1)+i;*lpDst = *lpSrc;}}memcpy(p_data,temp, wide*height);// 释放内存delete temp;}}}5-4.简述N*N中值滤波器的实现方法并编程实现1.取得图像大小,数据区,并把数据区复制到缓冲区2.取得N值3.循环取得各点像素值4.对以该点像素为中心的N*N屏蔽窗口包括的各点像素值进行排序,得到中间值5.把该点像素值置为中间值6.把缓冲区中改动的数据复制到原数据区中代码:void ZaoShengXiaoChuDib::GuDing(int YuZhi){LPBYTE p_data; //原图数据区指针int wide,height; //原图长、宽p_data=this->GetData (); //取得原图的数据区指针if(m_pBitmapInfoHeader->biBitCount<9) //灰度图像{wide=this->GetWidth ();height=this->GetHeight ();for(int j=0;j<height;j++){for(int i=0;i<wide;i++){if(*p_data>YuZhi) //灰度值大于给定阈值,置为255*p_data=255;else*p_data=0; //不大于置为0p_data++;}}}else //24位彩色{wide=this->GetWidth();height=this->GetHeight ();for(int j=0;j<height;j++){for(int i=0;i<wide;i++) //所有像素依次循环{if(*p_data>YuZhi) //若像素值不为0*p_data=255; //将其置为255else*p_data=0; //不大于置为0p_data++;}}}}5-5.简述十字型中值滤波器的实现方法并编程实现1.取得图像大小,数据区,并把数据区复制到缓冲区中2.取得N值3.循环取得各点像素值4.计算以该像素为中心的屏蔽窗口内灰度值中值5.把该点像素值置为中间值6.把缓冲区中改动的数据复制到原数据区中代码:void ZaoShengXiaoChuDib::shizi(int n){DWORD size;size=GetSize();BYTE* p_temp=new BYTE [size];memset(p_temp,255,size);intyy,xx,n2,nn,chuo,chg,m,medi,medi2,medi3,madom,mado[1000],mado2[1000],mado3[1000];BYTE *p_data; //原图数据区指针int wide,height; //原图长、宽if(n<3||n%2!=1)//检查取值是否为3.5.7等的奇数AfxMessageBox("请输入一个大于等于3的奇数");if(n>=3&&n%2==1)n2=(n-1)/2;nn=n+n-1;chuo=(nn-1)/2;p_data=this->GetData();//取得原图的数据区指针wide=this->GetWidth(); //取得原图的数据区宽height=this->GetHeight(); //取得原图的数据区高if(m_pBitmapInfoHeader->biBitCount<9) //灰度图像{//十字型中值滤波for(int j=n2;j<height-n2;j++)for(int i=n2;i<wide-n2;i++){//把十字型屏蔽窗口部分的所有像素值代入mado[m]//(代入含中心的垂直部分)m=0;for(yy=j-n2;yy<=j+n2;yy++){mado[m]=p_data[yy*wide+i];m++;}//(代入中心以外的的水平部分)for(xx=i-n2;xx<=i+n2;xx++){if(xx==i)continue;mado[m]=p_data[j*wide+xx];m++;}//把mado[m]的内容按下降顺序冒泡法分类do{chg=0;for(m=0;m<nn-1;m++){if(mado[m]<mado[m+1]){madom=mado[m];mado[m]=mado[m+1];mado[m+1]=madom;chg=1;}}}while(chg==1);//求中值medimedi=mado[chuo];p_temp[j*wide+i]=medi;}memcpy(m_pData,p_temp,size);delete p_temp;}else //24位彩色{//十字型中值滤波for(int j=n2;j<height-n2;j++)for(int i=n2;i<wide-n2;i++){//把十字型屏蔽窗口部分的所有像素值代入mado[m]//(代入含中心的垂直部分)m=0;for(yy=j-n2;yy<=j+n2;yy++){mado[m]=p_data[yy*wide*3+i*3];mado2[m]=p_data[yy*wide*3+i*3+1];mado3[m]=p_data[yy*wide*3+i*3+2];m++;}//(代入中心以外的的水平部分)for(xx=i-n2;xx<=i+n2;xx++){if(xx==i)continue;mado[m]=p_data[j*wide*3+xx*3];mado2[m]=p_data[j*wide*3+xx*3+1];mado3[m]=p_data[j*wide*3+xx*3+2];m++;}//把mado[m]的内容按下降顺序冒泡法分类do{chg=0;for(m=0;m<nn-1;m++){if(mado[m]<mado[m+1]){madom=mado[m];mado[m]=mado[m+1];mado[m+1]=madom;chg=1;}if(mado2[m]<mado2[m+1]){madom=mado2[m];mado2[m]=mado2[m+1];mado2[m+1]=madom;chg=1;}if(mado3[m]<mado3[m+1]){madom=mado3[m];mado3[m]=mado3[m+1];mado3[m+1]=madom;chg=1;}}}while(chg==1);//求中值medimedi=mado[chuo];medi2=mado2[chuo];medi3=mado3[chuo];p_temp[j*wide*3+i*3]=medi;p_temp[j*wide*3+i*3+1]=medi2;p_temp[j*wide*3+i*3+2]=medi3;}memcpy(m_pData,p_temp,wide*height*3);delete p_temp;}}。