博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
第四章 图像的灰度变换
阅读量:6278 次
发布时间:2019-06-22

本文共 13062 字,大约阅读时间需要 43 分钟。

VC++图像处理程序设计(第1版)    杨淑莹 编著     边奠英 主审
第四章 图像的灰度变换
Joanna-In-Hdu&Hust 手工打,印象更深刻
使用工具 VS2010 mfc
整本书的代码文件、测试图片和程序运行exe请在这里下载

1、此章的灰度代码的头文件:HuiDuDib.h:

1 #pragma once 2 class HuiDuDib:public CObject 3 { 4 protected: 5     CDib* dib; 6 public: 7     void Fei0(); 8     void GetDib(CDib *d); 9     void GuDing(int YuZhi);10     void ShuangYu(int low,int high,int mode);11     void FanSe();12     void ChuangKou(BYTE low,BYTE high);13     void ZheXian(BYTE X1,BYTE y1,BYTE X2,BYTE Y2);//优点是根据用户需要,拉伸感兴趣的物体细节,相对抑制不感兴趣的灰度级14     float* ZhiFangTu(bool i);//相比原书,改变了接口,为true返回小数的,为false返回整数的15     void FenBuJunHengHua();//减少像素个数少的灰度级,展宽灰度级个数多的,从而达到清晰图像的目的16     void PiPeiBianHuan(BYTE jishu,int* huidu,float *shuju);//jishu表示要匹配的灰度图有多少级,huidu中依次记录了从小到大每一个灰度值,shuju记录了每一个灰度值的gailv;对原图和目标灰度直方图进行灰度直方图均衡化,然后对于原图的每一个灰度级找到在目标灰度图中的灰度概率最相近的灰度,进行单映射变换,然后对原图进行灰度替换17     int PingJunHuiDu();//返回图像的平均灰度18 };

2、HuiDuDib.cpp:

1 #include"stdafx.h"  2 #include"CViewImage.h"  3 #include"CDib.h"  4 #include
5 #include"ZhiFangDlg.h" 6 #include"HuiDuDib.h" 7 8 void HuiDuDib::Fei0()//Luna的图片全是白色 9 { 10 LPBYTE p_data=dib->GetData(); 11 LPBYTE t; 12 int width=dib->GetWidth(); 13 int height=dib->GetHeight(); 14 int linebytes=dib->GetDibWidthBytes();//其实早已经写好了每行字节的获取方法,一直没用 15 for(int j=0;j
0) 20 *t=255; 21 } 22 } 23 void HuiDuDib::GetDib(CDib *d) 24 { 25 dib=d; 26 } 27 void HuiDuDib::GuDing(int YuZhi) 28 { 29 LPBYTE p_data,p; 30 p_data=dib->GetData(); 31 int width=dib->GetWidth(); 32 int height=dib->GetHeight(); 33 int linebytes=dib->GetDibWidthBytes(); 34 for(int j=0;j
GetData(); 47 LPBYTE t; 48 int width=dib->GetWidth(); 49 int height=dib->GetHeight(); 50 int linebytes=dib->GetDibWidthBytes(); 51 switch(mode) 52 { 53 case 0://0-255-0 54 for(int j=0;j
=high) 59 *t=0; 60 else 61 *t=255; 62 } 63 break; 64 case 1://255-0-255 65 for(int j=0;j
=high) 70 *t=255; 71 else 72 *t=0; 73 } 74 break; 75 } 76 77 } 78 void HuiDuDib::FanSe() 79 { 80 LPBYTE p_data=dib->GetData(); 81 LPBYTE t; 82 int width=dib->GetWidth(); 83 int height=dib->GetHeight(); 84 int linebytes=dib->GetDibWidthBytes(); 85 for(int j=0;j
GetData(); 95 LPBYTE t; 96 int width=dib->GetWidth(); 97 int height=dib->GetHeight(); 98 int linebytes=dib->GetDibWidthBytes(); 99 for(int j=0;j
high)106 *t=255;107 }108 }109 void HuiDuDib::ZheXian(BYTE X1,BYTE Y1,BYTE X2,BYTE Y2)110 {111 LPBYTE p_data=dib->GetData();112 LPBYTE t;113 int width=dib->GetWidth();114 int height=dib->GetHeight();115 int linebytes=dib->GetDibWidthBytes();116 for(int j=0;j
0&&*t<=X1)121 {122 *t=*t*(Y1/X1);123 }124 else if(*t
GetData();140 BYTE *temp;141 int width=dib->GetWidth();142 int height=dib->GetHeight();143 int linebytes=dib->GetDibWidthBytes();144 int i,j;145 for(j=0;j
GetData();171 fPs_R=ZhiFangTu(true);//这里是跟书处理不一样的172 //进行均衡化处理173 for(i=0;i<256;i++)174 {175 if(i==0)176 temp_r[0]=fPs_R[0];177 else178 temp_r[i]=temp_r[i-1]+fPs_R[i];179 nNs_R[i]=(int)(255.0f*temp_r[i]+0.5f);//+0.5f为了减少精度的缺失,满足四舍五入180 }181 int width=dib->GetWidth();182 int height=dib->GetHeight();183 unsigned char temp;184 int linebytes=dib->GetDibWidthBytes();185 //对各像素进行灰度转换186 for(j=0;j
GetData();201 long width=dib->GetWidth();202 long height=dib->GetHeight();203 gailv=ZhiFangTu(true);204 //计算原始累计直方图205 for(i=0;i<256;i++)206 {207 if(i==0)208 temp[0]=gailv[0];209 else210 temp[i]=temp[i-1]+gailv[i];211 gailv[i]=temp[i];212 }213 //计算规定的累积直方图214 for(i=0;i<256;i++)215 {216 if(i==0)217 temp[0]=shuju[0];218 else219 temp[i]=temp[i-1]+shuju[i];220 shuju[i]=temp[i];221 }222 for(i=0;i<256;i++)223 {224 //最接近的规定直方图灰度等级,用规定的直方图等级代替概率差不多的等级225 //让原来的直方图的形状大体接近规定的直方图226 int m_r=0;227 //最小差值228 float min_value_r=1;229 for(j=0;j
=0)235 now_value=gailv[i]-shuju[j];236 else237 now_value=shuju[j]-gailv[i];238 //寻找最接近的规定直方图灰度级239 if(now_value
GetDibWidthBytes();250 unsigned char t;251 for(j=0;j

3、其中用于显示直方图的文件:

头文件ZhiFangDlg.h:

1 #pragma once 2  3  4 // ZhiFangDlg dialog 5  6 class ZhiFangDlg : public CDialogEx 7 { 8     DECLARE_DYNAMIC(ZhiFangDlg) 9 10 public:11     ZhiFangDlg(CWnd* pParent = NULL);   // standard constructor12     virtual ~ZhiFangDlg();13     void OnPaint();14     void SetData(float* data);15 16 // Dialog Data17     enum { IDD = 139 };//这里总是出问题,所以直接写成数字了18 19 protected:20     virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support21     float *data;22     DECLARE_MESSAGE_MAP()23 public:24     afx_msg void OnBnClickedButton1();25 };

ZhiFangDlg.cpp:

1 // ZhiFangDlg.cpp : implementation file  2 //  3   4 #include "stdafx.h"  5 #include "MfcPictureProcessing.h"  6 #include "ZhiFangDlg.h"  7 #include "afxdialogex.h"  8   9  10 // ZhiFangDlg dialog 11  12 IMPLEMENT_DYNAMIC(ZhiFangDlg, CDialogEx) 13  14 ZhiFangDlg::ZhiFangDlg(CWnd* pParent /*=NULL*/) 15     : CDialogEx(ZhiFangDlg::IDD, pParent) 16 { 17     data=NULL; 18 } 19  20 ZhiFangDlg::~ZhiFangDlg() 21 { 22 } 23  24 void ZhiFangDlg::DoDataExchange(CDataExchange* pDX) 25 { 26     CDialogEx::DoDataExchange(pDX); 27 } 28  29  30 BEGIN_MESSAGE_MAP(ZhiFangDlg, CDialogEx) 31     ON_BN_CLICKED(IDC_BUTTON1, &ZhiFangDlg::OnBnClickedButton1) 32 END_MESSAGE_MAP() 33  34  35 // ZhiFangDlg message handlers 36 void ZhiFangDlg::SetData(float *d) 37 { 38     data=d; 39 } 40 void ZhiFangDlg::OnPaint() 41 { 42     // 43     //CPaintDC dc(this);//用这个画不出来 44     CDC *dc=GetDC(); 45     CPen* pPen=new CPen;//创建画笔 46     pPen->CreatePen(PS_SOLID,1,RGB(0,0,0));//创建一支黑笔 47     CGdiObject *pOldPen=dc->SelectObject(pPen);//选中新画笔,保存旧画笔 48     int i=0; 49     CString str; 50     CPoint OPos(14,188),NowPos;//绘制坐标系 51     //绘制X坐标轴 52     dc->MoveTo(OPos); 53     NowPos.x=284; 54     NowPos.y=188; 55     dc->LineTo(NowPos); 56     //绘制箭头 57     dc->LineTo(279,183); 58     dc->MoveTo(NowPos); 59     dc->LineTo(279,193); 60     //绘制x轴坐标系数 61     //下面单独挑出来是为了好看 62     i=0; 63     dc->MoveTo(OPos.x+i,OPos.y); 64     dc->LineTo(CPoint(OPos.x+i,OPos.y+5)); 65     str.Format(_T("%d"),i); 66     dc->TextOutW(OPos.x+i-5,OPos.y+7,str); 67     for(i=10;i<256;i+=10)//这里有修改 68     { 69         if(i%10==0)//绘制竖杠 70         { 71             dc->MoveTo(OPos.x+i,OPos.y); 72             dc->LineTo(CPoint(OPos.x+i,OPos.y+5)); 73         } 74         if(i%40==0)//绘制字 75         { 76             str.Format(_T("%d"),i); 77             dc->TextOutW(OPos.x+i-10,OPos.y+7,str); 78         } 79     } 80     //绘制y轴坐标系数 81     dc->MoveTo(OPos); 82     NowPos.x=OPos.x; 83     NowPos.y=4; 84     dc->LineTo(NowPos); 85     //绘制箭头 86     dc->LineTo(NowPos.x-5,NowPos.y+5);//画笔最后停在哪里,绘制的中心就在哪里 87     dc->MoveTo(NowPos); 88     dc->LineTo(NowPos.x+5,NowPos.y+5); 89     //寻找数组最大的数据 90     float max=0; 91     for(i=0;i<256;i++) 92     { 93         if(max
MoveTo(OPos.x,OPos.y-Ystep*i);103 dc->LineTo(OPos.x+5,OPos.y-Ystep*i);104 str.Format(_T("%f"),max);//这里修改了105 dc->TextOutW(20,OPos.y-Ystep*i-20,str); 106 107 //绘制灰度直方图108 for(i=0;i<256;i++)109 {110 NowPos.x=OPos.x+i;111 NowPos.y=OPos.y;112 dc->MoveTo(NowPos);113 NowPos.y=187-20*Ystep*data[i]/max;//计算比例,用20*Ystep,不能用175,因为中间精度缺失了太多114 dc->LineTo(NowPos);115 }116 dc->SelectObject(pOldPen);117 118 delete pPen;119 //Invalidate();120 }121 122 void ZhiFangDlg::OnBnClickedButton1()123 {124 if(data!=NULL)125 OnPaint();126 }

4、用于调用上面文件的运行函数:

1 void CMfcPictureProcessingDlg::On32797()//灰度非零取一  2 {  3     if(filePath.Compare(_T(""))!=0)  4     {  5         CDib dib;  6         dib.LoadFile(filePath);  7         if(dib.m_valid)  8         {  9             HuiDuDib d; 10             d.GetDib(&dib); 11             d.Fei0(); 12             CViewImage i; 13             i.GetDib(&dib); 14             CDC *pDC=GetDC(); 15             i.OnDraw2(pDC,dib.GetWidth()+5,0); 16         } 17     } 18     else{ 19         MessageBox(_T("请先选择文件!"),_T("提示"),MB_OK); 20     } 21 } 22  23  24 void CMfcPictureProcessingDlg::On32798()//灰度固定阈值 25 { 26     if(filePath.Compare(_T(""))!=0) 27     { 28         CDib dib; 29         dib.LoadFile(filePath); 30         if(dib.m_valid) 31         { 32             HuiDuDib hui; 33             hui.GetDib(&dib); 34             GuDingDlg gd; 35             gd.DoModal(); 36             if(gd.ifok) 37             { 38                 hui.GuDing(gd.GetYuZhi()); 39                 CViewImage i; 40                 i.GetDib(&dib); 41                 CDC *pDC=GetDC(); 42                 i.OnDraw2(pDC,dib.GetWidth()+5,0); 43             } 44         } 45     } 46     else{ 47         MessageBox(_T("请先选择文件!"),_T("提示"),MB_OK); 48     } 49 } 50  51 void CMfcPictureProcessingDlg::On32800()//灰度双阈值 52 { 53     if(filePath.Compare(_T(""))!=0) 54     { 55         CDib dib; 56         dib.LoadFile(filePath); 57         if(dib.m_valid) 58         { 59             HuiDuDib hd; 60             hd.GetDib(&dib); 61             ShuangYuZhiDlg s; 62             s.DoModal(); 63             if(s.ifok) 64             { 65                 hd.ShuangYu(s.GetLow(),s.GetHigh(),s.GetMode()); 66                 CViewImage imageview; 67                 imageview.GetDib(&dib); 68                 CDC *pDC=GetDC(); 69                 imageview.OnDraw2(pDC,dib.GetWidth()+5,0); 70             } 71         } 72     } 73     else{ 74         MessageBox(_T("请先选择文件!"),_T("提示"),MB_OK); 75     } 76 } 77  78  79 void CMfcPictureProcessingDlg::On32801()//灰度反色变换 80 { 81     if(filePath.Compare(_T(""))!=0) 82     { 83         CDib dib; 84         dib.LoadFile(filePath); 85         if(dib.m_valid) 86         { 87             CDC *pDC=GetDC(); 88             HuiDuDib h; 89             h.GetDib(&dib); 90             h.FanSe(); 91             CViewImage imageview; 92             imageview.GetDib(&dib); 93             imageview.OnDraw2(pDC,dib.GetWidth()+5,0); 94         } 95     } 96     else{ 97         MessageBox(_T("请先选择文件!"),_T("提示"),MB_OK); 98     } 99 }100 101 102 void CMfcPictureProcessingDlg::On32802()//灰度窗口变换103 {104     if(filePath.Compare(_T(""))!=0)105     {106         CDib dib;107         dib.LoadFile(filePath);108         if(dib.m_valid)109         {110             ChuangkouDlg k;111             k.DoModal();112             if(k.ifok)113             {114                 HuiDuDib h;115                 h.GetDib(&dib);116                 h.ChuangKou(k.GetLow(),k.GetHigh());117                 CDC *pDC=GetDC();118                 CViewImage imageview;119                 imageview.GetDib(&dib);120                 imageview.OnDraw2(pDC,dib.GetWidth()+5,0);121             }122         } 123     }124     else{125         MessageBox(_T("请先选择文件!"),_T("提示"),MB_OK);126     }127 }128 129 130 void CMfcPictureProcessingDlg::On32803()//折线变换131 {132     if(filePath.Compare(_T(""))!=0)133     {134         CDib dib;135         dib.LoadFile(filePath);136         if(dib.m_valid)137         {138             ZheXianDlg z;139             z.DoModal();140             if(z.ifok)141             {142                 CDC *pDC=GetDC();143                 HuiDuDib hdib;144                 hdib.GetDib(&dib);145                 hdib.ZheXian(z.GetX1(),z.GetY1(),z.GetX2(),z.GetY2());146                 CViewImage imageview;147                 imageview.GetDib(&dib);148                 imageview.OnDraw2(pDC,dib.GetWidth()+5,0);149             }150         }151     }152     else{153         MessageBox(_T("请先选择文件!"),_T("提示"),MB_OK);154     }155 }156 157 158 void CMfcPictureProcessingDlg::On32804()//灰度直方图159 {160     if(filePath.Compare(_T(""))!=0)161     {162         CDib dib;163         dib.LoadFile(filePath);//这里为了练习效果,只显示原图的164         if(dib.m_valid)165         {166             HuiDuDib hdib;167             hdib.GetDib(&dib);168             float *p=hdib.ZhiFangTu(true);169             //开始画直方图170             ZhiFangDlg d;171             d.SetData(p);172             d.DoModal();173             delete []p;174         }175     }176     else{177         MessageBox(_T("请先选择文件!"),_T("提示"),MB_OK);178     }179 }180 181 182 void CMfcPictureProcessingDlg::On32805()//灰度分布均衡化183 {184     if(filePath.Compare(_T(""))!=0)185     {186         CDib dib;187         dib.LoadFile(filePath);188         if(dib.m_valid)189         {190             HuiDuDib hdib;191             hdib.GetDib(&dib);192             hdib.FenBuJunHengHua();193             CViewImage imageview;194             imageview.GetDib(&dib);195             CDC* pDC=GetDC();196             imageview.OnDraw2(pDC,dib.GetWidth()+5,0);197             float* p=hdib.ZhiFangTu(true);198             ZhiFangDlg d;199             d.SetData(p);200             d.DoModal();201             delete []p;202         }203     }204     else{205         MessageBox(_T("请先选择文件!"),_T("提示"),MB_OK);206     }207 }

 

5、运行:

结束~

 

转载于:https://www.cnblogs.com/studylyn/p/7862218.html

你可能感兴趣的文章
usb键鼠驱动分析【钻】
查看>>
shell中while循环的陷阱
查看>>
Java 系书籍,,,,,,,,,,,,,
查看>>
binlog 轻松的找到没有及时提交的事物(infobin工具
查看>>
windows下如何创建没有名字的.htaccess文件
查看>>
关于Unity中物体分别在本地和世界坐标系对应方向的移动
查看>>
引用外部jquery.js
查看>>
WebLogic 11g重置用户密码
查看>>
Python sin() 函数
查看>>
Python isalnum() 方法
查看>>
Nginx负载均衡器处理Session共享的几种方法(转)
查看>>
转 MySQL问题排查工具介绍
查看>>
Linux、apache 无法使用PHP创建目录和文件
查看>>
hi模板文件报乱码问题
查看>>
Java 远程通讯技术及原理分析
查看>>
ORM框架之------Dapper,Net下无敌的ORM
查看>>
R语言绘图时的边界碰撞问题
查看>>
深度可分离卷积结构(depthwise separable convolution)计算复杂度分析
查看>>
IntelliJ IDEA 常用设置讲解
查看>>
软件的描述x
查看>>