VC++开发数字图像处理系统2

本节主要内容是将图片显示到控件上。

这里我们借助Visual Studio提供给我们的Gdiplus工具将图片显示到控件上。

一、首先简要介绍Gdiplus的配置方法:

1    在单文档应用程序中使用GDI+创建一个单文档程序

1.1   添加包含文件和类库,方法:在stdafx.h文件中添加下面两行代码

#pragma comment(lib,”gdiplus.lib”)

using namespace Gdiplus;

  或者【项目】|【属性】,->【链接器】|【输入】->【附加依赖项】,在框中输入gdiplus.lib

1.2  在应用程序项目的应用类中,添加一个成员变量

ULONG_PTR m_gdiplusToken;


其中,ULONG_PTR是一个DWORD数据类型,该成员变量用来保存GDI+被初始化后在应用程序中的GDI+标识,以便能在应用程序退出后,引用该标识来调用Gdiplus:: GdiplusShutdown来关闭GDI+

1.3   在应用类中添加ExitInstance的重载来关闭GDI+

int CEXXXApp::ExitInstance()

{

                Gdiplus::GdiplusShutdown(m_gdiplusToken);

                return CWinApp::ExitInstance();

}

 

1.4  在应用类的InitInstance函数中添加GDI+的初始化代码

BOOL CEx_GDIPlusApp::InitInstance()

{

    ......

    CWinApp::InitInstance();

    Gdiplus::GdiplusStartupInput gdiplusStartupInput;

Gdiplus::GdiplusStartup(&m_gdiplusToken,&gdiplusStartupInput,NULL);

              ......

 }         

2    在基于对话框应用程序中使用GDI+

创建一个对话框应用程序

2.1 添加包含文件和类库,方法:在stdafx.h文件中添加下面两行代码

#pragma comment(lib,”gdiplus.lib”)

using namespace Gdiplus;

2.2 步骤同单文档应用程序

3    VS2010中的MFC中配置GDI+
首先,VS2010中已经有GDI+SDK包的,不需要额外下载
1)stdafx.h文件中加入下面3行代码,添加相应的头文件和库
  

#pragma comment( lib, "gdiplus.lib" )
#include "gdiplus.h"
using namespace Gdiplus;


2)在应用程序项目的应用类中,添加一个成员变量或者定义一个全局变量ULONG_PTR m_gdiplusToken;
其中,ULONG_PTR是一个DWORD数据类型,该成员变量用来保存GDI+被初始化后在应用程序中的GDI+标识,以便能在应用程序退出后,引用该标识来调用Gdiplus:: GdiplusShutdown来关闭GDI+
3)使用GDI+函数前,先,最好放在OnInitDialog()中
 

Gdiplus::GdiplusStartupInput gdiplusStartupInput;
Gdiplus::GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL); 


4)使用完GDI+函数后,需要卸载GDI+
  

Gdiplus::GdiplusShutdown(m_gdiplusToken);

这就是基本的配置了

当然,为了避免命名冲突,也可以将

#pragma comment(lib,”gdiplus.lib”)

using namespace Gdiplus;

 

只添加到我们要使用Gdiplus库的头文件中去。

二、将图片显示到控件上

这里我们插入一个对话框资源:IDC_ThresholdDlg

再为这个资源添加一个类:CThreshholdDlg

 /** CThreshholdDlg.h*/
1
#pragma once 2 3 #include "resource.h" 4 #include "Dib.h" 5 #include "Threshold.h" 6 #pragma comment(lib,"gdiplus.lib") 7 #include <GdiPlus.h> 8 using namespace Gdiplus; 9 // CThresholdDlg 对话框 10 11 class CThresholdDlg : public CDialog 12 { 13 DECLARE_DYNAMIC(CThresholdDlg) 14 15 public: 16 CThresholdDlg(CWnd* pParent = NULL); // 标准构造函数 17 virtual ~CThresholdDlg(); 18 19 // 对话框数据 20 enum { IDD = IDD_Threshold }; 21 22 public: 23 CDib dib; 24 CStatic m_staBmp; 25 CString m_BmpFilePath; 26 CString m_BmpFileName; 27 public: 28 CDib* GetDib(); 29 void DrawBitmap(); 30 protected: 31 virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 32 33 DECLARE_MESSAGE_MAP() 34 public: 35 afx_msg void OnBnClickedOpenBmp(); 36 afx_msg void OnBnClickedOutsthreshold(); 37 afx_msg void OnBnClickedAdaptivethreshold(); 38 afx_msg void OnBnClickedSaveresult(); 39 };

 

  1 /**ThresholdDlg.cpp*/ 
  2 //
  3 
  4 #include "stdafx.h"
  5 #include "ImgPro.h"
  6 #include "ThresholdDlg.h"
  7 #include "afxdialogex.h"
  8 
  9 
 10 // CThresholdDlg 对话框
 11 
 12 IMPLEMENT_DYNAMIC(CThresholdDlg, CDialog)
 13 
 14 CThresholdDlg::CThresholdDlg(CWnd* pParent /*=NULL*/)
 15     : CDialog(CThresholdDlg::IDD, pParent)
 16 {
 17 
 18 }
 19 
 20 CThresholdDlg::~CThresholdDlg()
 21 {
 22 }
 23 
 24 void CThresholdDlg::DoDataExchange(CDataExchange* pDX)
 25 {
 26     CDialog::DoDataExchange(pDX);
 27     DDX_Control(pDX,IDC_STATIC,m_staBmp);
 28 }
 29 
 30 
 31 BEGIN_MESSAGE_MAP(CThresholdDlg, CDialog)
 32     ON_BN_CLICKED(IDC_Open_BMP, &CThresholdDlg::OnBnClickedOpenBmp)
 33     ON_BN_CLICKED(IDC_OutsThreshold, &CThresholdDlg::OnBnClickedOutsthreshold)
 34     ON_BN_CLICKED(IDC_AdaptiveThreshold, &CThresholdDlg::OnBnClickedAdaptivethreshold)
 35     ON_BN_CLICKED(IDC_SaveResult, &CThresholdDlg::OnBnClickedSaveresult)
 36 END_MESSAGE_MAP()
 37 
 38 CDib* CThresholdDlg::GetDib()
 39 {
 40     return &dib;
 41 }
 42 
 43 void CThresholdDlg::DrawBitmap(void)
 44     {
 45         CDC* pDC=m_staBmp.GetDC();
 46         Graphics graph(pDC->GetSafeHdc());
 47         CRect rect;
 48         m_staBmp.GetClientRect(rect);
 49         pDC->FillRect(rect, &CBrush(RGB(211, 211, 211)));
 50         CSize size;
 51         size.cx=rect.Width();
 52         size.cy=rect.Height();
 53         dib.Draw(pDC,CPoint(0,0),size);
 54         ReleaseDC(pDC);
 55     }
 56 // CThresholdDlg 消息处理程序
 57 
 58 
 59 void CThresholdDlg::OnBnClickedOpenBmp()
 60 {
 61     // TODO: 在此添加控件通知处理程序代码
 62     LPCTSTR lpszFilter=L"BMP Files(*.bmp)|*.bmp|JPG Files(*.jpg)|*.jpg|All Files(*.*)|*.*||";
 63     CFileDialog dlg(TRUE,NULL,NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT|OFN_EXPLORER,lpszFilter,NULL);
 64     CFile file;
 65     if(dlg.DoModal()==IDOK)
 66     {
 67         m_BmpFilePath=dlg.GetPathName();
 68         if(file.Open(m_BmpFilePath,CFile::modeRead|CFile::shareDenyNone,NULL)==0)
 69         {
 70             return;
 71         }
 72         dib.LoadFromFile(m_BmpFilePath);
 73         DrawBitmap();
 74     }
 75 }
 76 
 77 
 78 void CThresholdDlg::OnBnClickedOutsthreshold()
 79 {
 80     // TODO: 在此添加控件通知处理程序代码
 81     CThreshold threshold(GetDib());
 82     //threshold.m_pDib=GetDib();
 83     if(!dib.IsGrade())
 84         {
 85             dib.RgbToGrade();
 86             DrawBitmap();
 87         }
 88         else
 89         {;}
 90     threshold.OtusThreshold();
 91     DrawBitmap();
 92 }
 93 
 94 
 95 void CThresholdDlg::OnBnClickedAdaptivethreshold()
 96 {
 97     // TODO: 在此添加控件通知处理程序代码
 98     CThreshold threshold(GetDib());
 99     //threshold.m_pDib=GetDib();
100     if(!dib.IsGrade())
101         {
102             dib.RgbToGrade();
103             DrawBitmap();
104         }
105         else
106         {;}
107     threshold.AdaptiveThreshold();
108     DrawBitmap();
109 }
110 
111 
112 void CThresholdDlg::OnBnClickedSaveresult()
113 {
114     // TODO: 在此添加控件通知处理程序代码
115     LPCTSTR lpszFilter=L"BMP Files(*.bmp)|*.bmp|All Files(*.*)|*.*||";
116         CFileDialog dlg(FALSE,NULL,NULL,OFN_HIDEREADONLY|OFN_EXPLORER,lpszFilter,NULL);
117         if(dlg.DoModal()!=IDOK)
118             return;
119         dib.SaveToFile(dlg.GetPathName());
120 }

Threshold.h

 /** Threshold.h*/
1
#pragma once 2 3 #include "Dib.h" 4 5 class CThreshold 6 { 7 public: 8 CThreshold(); 9 CThreshold(CDib *pDib); 10 public: 11 ~CThreshold(void); 12 public: 13 void AdaptiveThreshold(void); 14 void OtusThreshold(void); 15 private: 16 CDib * m_pDib; 17 };

Threshold.cpp

  /**Threshold.cpp*/
1
#include "StdAfx.h" 2 #include "Threshold.h" 3 #include "math.h" 4 5 CThreshold::CThreshold() 6 { 7 } 8 9 CThreshold::CThreshold(CDib *pDib) 10 { 11 m_pDib = pDib; 12 } 13 14 CThreshold::~CThreshold(void) 15 { 16 } 17 18 //======================================================= 19 // 函数功能: 最大方差阈值分割 20 // 输入参数: 无 21 // 返回值: 无 22 //======================================================= 23 void CThreshold::OtusThreshold(void) 24 { 25 // 循环变量 26 int i, j; 27 28 // 原图数据区指针 29 LPBYTE p_data; 30 p_data = m_pDib->GetData(); 31 32 // 图像每行像素所占的字节数 33 int nLineByte = m_pDib->GetLineByte(); 34 35 // 图像的宽度 36 int nWidth = m_pDib->GetWidth(); 37 38 // 图像的高度 39 int nHeight = m_pDib->GetHeight(); 40 41 // 灰度直方图数组,并初始化 42 int nGrayHistogram[256]; 43 memset(nGrayHistogram, 0, sizeof(nGrayHistogram)); 44 45 // 统计各个灰度级对应的像素个数,并存放到灰度直方图数组中 46 int nPixel; 47 for (j = 0; j < nHeight; j ++) 48 for (i = 0; i < nWidth; i ++) 49 { 50 // 获取当前像素点的灰度值 51 nPixel = p_data[nLineByte * j + i]; 52 53 // 对灰度值统计计数 54 nGrayHistogram[nPixel] ++; 55 } 56 57 // c0组和c1组的均值 58 float u0, u1; 59 60 // c0组和c1组的概率 61 float w0, w1; 62 63 // c0组的像素总数 64 int nCount0; 65 66 // 阈值和最佳阈值(对应方差最大时的阈值) 67 int nT, nBestT; 68 69 // 方差和最大方差 70 float fVaria, fMaxVaria = 0; 71 72 // 统计直方图中像素点的总数,并存放到nSum中 73 int nSum=0; 74 for(i = 0; i < 256; i ++) 75 nSum += nGrayHistogram[i]; 76 77 78 // 令阈值nT从0遍历到255 79 for(nT = 0; nT < 256; nT ++) 80 { 81 // 当阈值为nT时,计算c0组的均值和概率 82 u0 = 0; 83 nCount0 = 0; 84 for(i = 0; i <= nT; i++) 85 { 86 u0 += i * nGrayHistogram[i]; 87 nCount0 += nGrayHistogram[i]; 88 } 89 u0 /= nCount0; 90 w0 = (float) nCount0 / nSum; 91 92 // 当阈值为nT时,计算c1组的均值和概率 93 u1 = 0; 94 for(i = nT+1; i < 256; i ++) 95 u1 += i * nGrayHistogram[i]; 96 u1 /= (nSum - nCount0); 97 w1 = 1 - w0; 98 99 // 计算两组间的方差 100 fVaria = w0 * w1 * (u0 - u1) * (u0 - u1); 101 102 // 记录最大方差和最佳阈值 103 if(fVaria > fMaxVaria) 104 { 105 fMaxVaria = fVaria; 106 nBestT = nT; 107 } 108 } 109 110 // 利用最佳阈值对原图像作分割处理 111 for(j = 0; j < nHeight; j ++) 112 for(i = 0; i < nWidth; i ++) 113 { 114 if(p_data[j * nLineByte + i] < nBestT) 115 p_data[j * nLineByte + i] = 0; 116 else 117 p_data[j * nLineByte + i] = 255; 118 } 119 } 120 121 122 //======================================================= 123 // 函数功能: 自适应阈值分割 124 // 输入参数: 无 125 // 返回值: 无 126 //======================================================= 127 void CThreshold::AdaptiveThreshold(void) 128 { 129 // 循环变量 130 int i,j; 131 132 // 原图像数据区指针 133 LPBYTE p_data; 134 p_data = m_pDib->GetData(); 135 136 // 图像每行像素所占的字节数 137 int nLineByte = m_pDib->GetLineByte(); 138 139 // 图像的宽度 140 int nWidth = m_pDib->GetWidth(); 141 142 // 图像的高度 143 int nHeight = m_pDib->GetHeight(); 144 145 // 局部阈值 146 int nThreshold[2][2]; 147 148 // 子图像的灰度平均值 149 int nAvgValue; 150 151 // 对左上图像逐点扫描,计算该子图像的灰度平均值 152 nAvgValue = 0; 153 for(j = nHeight / 2; j < nHeight; j ++) 154 for(i = 0; i < nWidth / 2; i ++) 155 nAvgValue += p_data[j * nLineByte + i]; 156 nAvgValue /= ((nHeight / 2) * (nLineByte / 2)); 157 158 // 设置阈值为子图像的平均值 159 nThreshold[0][0] = nAvgValue; 160 161 // 对左上图像逐点扫描并进行阈值分割 162 for(j = nHeight / 2; j < nHeight; j ++) 163 for(i = 0; i < nWidth / 2; i ++) 164 { 165 if(p_data[j * nLineByte + i] < nThreshold[0][0]) 166 p_data[j * nLineByte + i] = 0; 167 else 168 p_data[j * nLineByte + i] = 255; 169 } 170 171 // 对右上图像逐点扫描,计算该子图像的灰度平均值 172 nAvgValue = 0; 173 for(j = nHeight / 2; j < nHeight; j ++) 174 for(i = nWidth / 2; i < nWidth; i ++) 175 nAvgValue += p_data[j * nLineByte + i]; 176 nAvgValue /= ((nHeight / 2) * (nLineByte / 2)); 177 178 // 设置阈值为子图像的平均值 179 nThreshold[0][1] = nAvgValue; 180 181 // 对右上图像逐点扫描并进行阈值分割 182 for(j = nHeight / 2; j < nHeight; j ++) 183 for(i = nWidth / 2; i < nWidth; i ++) 184 { 185 if(p_data[j * nLineByte + i] < nThreshold[0][0]) 186 p_data[j * nLineByte + i] = 0; 187 else 188 p_data[j * nLineByte + i] = 255; 189 } 190 191 // 对左下图像逐点扫描,计算该子图像的灰度平均值 192 nAvgValue = 0; 193 for(j = 0; j < nHeight / 2; j ++) 194 for(i = 0; i < nWidth / 2; i ++) 195 nAvgValue += p_data[j * nLineByte + i]; 196 nAvgValue /= ((nHeight / 2) * (nLineByte / 2)); 197 198 // 设置阈值为子图像的平均值 199 nThreshold[1][0] = nAvgValue; 200 201 // 对左下图像逐点扫描并进行阈值分割 202 for(j = 0; j < nHeight / 2; j ++) 203 for(i = 0; i < nWidth / 2; i ++) 204 { 205 if(p_data[j * nLineByte + i] < nThreshold[0][0]) 206 p_data[j * nLineByte + i] = 0; 207 else 208 p_data[j * nLineByte + i] = 255; 209 } 210 211 // 对右下图像逐点扫描,计算该子图像的灰度平均值 212 nAvgValue = 0; 213 for(j = 0; j < nHeight / 2; j ++) 214 for(i = nWidth / 2; i < nWidth; i ++) 215 nAvgValue += p_data[j * nLineByte + i]; 216 nAvgValue /= ((nHeight / 2) * (nLineByte / 2)); 217 218 // 设置阈值为子图像的平均值 219 nThreshold[1][1] = nAvgValue; 220 221 // 对右下下图像逐点扫描并进行阈值分割 222 for(j = 0; j < nHeight / 2; j ++) 223 for(i = nWidth / 2; i < nWidth;i ++) 224 { 225 if(p_data[j * nLineByte + i] < nThreshold[0][0]) 226 p_data[j * nLineByte + i] = 0; 227 else 228 p_data[j * nLineByte + i] = 255; 229 } 230 }

最后我们在视图类的实现(C*View.cpp)文件里添加命令响应函数:

/** C**View.cpp*/
1
void CImgProView::OnThreshhold() 2 { 3 // TODO: 在此添加命令处理程序代码 4 CThresholdDlg thresholddlg; 5 thresholddlg.DoModal(); 6 }

注:Dib.h和Dib.cpp文件在

VC++2010开发数字图像系统1

中给出

转载于:https://www.cnblogs.com/sxzheng/archive/2013/06/01/3112675.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
本书用面向对象的方法向读者介绍了用Visual C++进行数字图像处理的方法和技巧。全书共分13章,内容涵盖了数字图像概述、Visual C++数字图像编程基础、图像的几何变换、图像的灰度变换、图像的正交变换、图像增强、图像复原、图像的压缩编码、边缘检测与图像分析、图像的数学形态学运算、图像融合,以及图像特技显示等,在本书最后综合运用了图像处理的多种理论和方法实现了一个人脸检测的案例,以助于读者对各种图像处理方法的系统掌握和综合应用。. 在进行原理介绍时,力求通俗易懂,简明扼要而又不失完整性。在代码实现时力求简洁明了,注释详尽,为读者的阅读和理解提供最大便利。.. 本书的特色决定了本书不但适用于初、中级读者,其中的部分内容对高级读者也有一定的参考价值,同时也可用作高校相关专业师生的参考教材。... 【目录信息】 第1章 数字图像概述. 1.1 数字图像概论 1.2 数字图像的存储 1.3 BMP图像文件格式 1.4 TIFF图像文件格式 1.5 JPEG图像文件格式 1.6 PNG图像文件格式 1.7 小结 第2章 数字图像编程基础 2.1 图像和调色板的基本概念 2.2 GDI位图(DDB) 2.3 设备无关位图(DIB) 2.4 构造CDib类 2.5 使用CDib类读写BMP文件示例 2.6 小结 第3章 图像增强 3.1 灰度变换修整法 3.2 直方图修整法 << 查看详细目录 【前言】 20世纪20年代,图像处理首次应用于改善伦敦和纽约之间通过海底电缆传送的图片质量。经过几十年的研究与发展,数字图像处理的理论和方法进一步完善,应用领域更加广阔,已经成为一门新兴的学科,并在向更高级的方向发展。如在景物理解和计算机视觉(机器视觉)方面,图像处理已由二维处理发展到三维理解或解释。近几年来,随着计算机和各个相关领域研究的迅速发展,科学计算可视化、多媒体技术等研究和应用的兴起,数字图像处理从一个专门领域的学科,变成了一种新型的科学研究和人机界面的工具。. Visual C++是Microsoft公司推出的一种高度综合性能的开发Win32环境程序,面向对象的可视化集成编程系统。用..

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值