欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 金融 > 基于单文档的MFC图像分割

基于单文档的MFC图像分割

2025/3/15 4:49:39 来源:https://blog.csdn.net/weixin_45794330/article/details/140837620  浏览:    关键词:基于单文档的MFC图像分割

目录

Dib.h

Dib.cpp

EdgeDetection.h

EdgeDetection.cpp

Threshold.h

Threshold.cpp

基于单文档的图像分割View.h

基于单文档的图像分割View.cpp


1.新建文档

2.主要类代码

Dib.h

//======================================================================
// 内容: 设备无关位图类-头文件
// 功能: (1)位图的加载与保存;
//        (2)判断位图是否有效、获取位图的文件名;
//        (3)获取位图的长、宽、大小等信息;
//        (4)判断位图是否含有颜色表、获取位图颜色表、根据颜色表生成调
//             色板、使用颜色数、每个像素所占位数、每行像素所占位数;
//        (5)获取位图数据;
//        (6)显示位图;
//        (7)将彩色位图转换成灰度位图;
//        (8)将灰度位图转换成彩色位图;
// 作者: 李平科
// 联系: lipingke@126.com
// 日期: 2009-7-26
//======================================================================#pragma once#include "afx.h"class CDib : public CObject
{
public:// 构造函数CDib(void);// 析构函数~CDib(void);// 从文件加载位图BOOL LoadFromFile(LPCTSTR lpszPath);// 将位图保存到文件BOOL SaveToFile(LPCTSTR lpszPath);// 获取位图文件名LPCTSTR GetFileName();// 获取位图大小DWORD GetSize();// 获取位图宽度UINT GetWidth();// 获取位图高度UINT GetHeight();// 获取位图的宽度和高度CSize GetDimension();// 获取像素所占位数UINT GetBitCount();// 获取位图颜色数UINT GetNumOfColor();// 获取位图颜色表LPRGBQUAD GetRgbQuad();// 获取位图数据LPBYTE GetData();// 获取灰度位图数据LPBYTE GetGradeData();// 获取彩色位图数据LPBYTE GetColorData();// 根据颜色表生成调色板BOOL MakePalette();// 显示位图BOOL Draw(CDC *pDC, CPoint origin, CSize size);// 获取每行像素所占字节数UINT GetLineByte();// 彩色位图转灰度位图BOOL RgbToGrade();// 灰度位图转彩色位图BOOL GradeToRgb();// 判断是否含有颜色表BOOL HasRgbQuad();// 判断是否是灰度图BOOL IsGrade();// 判断位图是否有效BOOL IsValid();  // 清理空间void Empty();protected:// 计算位图颜色数UINT CalcNumOfColor();private:// 位图文件名char m_fileName[_MAX_PATH];// 位图文件头指针LPBITMAPFILEHEADER m_lpBmpFileHeader;// 位图指针(包含除位图文件头的所有内容)LPBYTE m_lpDib; // 需要动态分配和释放// 位图信息指针LPBITMAPINFO m_lpBmpInfo;// 位图信息头指针LPBITMAPINFOHEADER m_lpBmpInfoHeader;  // 位图颜色表指针LPRGBQUAD m_lpRgbQuad; // 位图数据指针LPBYTE m_lpData; // 灰度位图数据指针(位图转换时用)LPBYTE m_lpGradeData; // 需要动态分配和释放// 彩色位图数据指针(位图转换时用)LPBYTE m_lpColorData; // 需要动态分配和释放 // 颜色表长度UINT m_uRgbQuadLength;// 位图颜色数UINT m_uNumOfColor;// 每像素占的位数UINT m_uBitCount;  // 每行像素所占字节数,为4的倍数UINT m_uLineByte;// 是否有颜色表BOOL m_bHasRgbQuad;// 调色板句柄HPALETTE m_hPalette;// 位图是否有效BOOL m_bValid;
};

Dib.cpp

//======================================================================
// 内容: 设备无关位图类-源文件
// 功能: (1)位图的加载与保存;
//        (2)判断位图是否有效、获取位图的文件名;
//        (3)获取位图的长、宽、大小等信息;
//        (4)判断位图是否含有颜色表、获取位图颜色表、根据颜色表生成调
//             色板、使用颜色数、每个像素所占位数、每行像素所占位数;
//        (5)获取位图数据;
//        (6)显示位图;
//        (7)将彩色位图转换成灰度位图;
//        (8)将灰度位图转换成彩色位图;
// 作者: 李平科
// 联系: lipingke@126.com
// 日期: 2009-7-26
//======================================================================#include "StdAfx.h"
#include "Dib.h"//=======================================================
// 函数功能: 构造函数
// 输入参数: 无
// 返回值:   无
//=======================================================
CDib::CDib(void)
{m_lpBmpFileHeader = NULL;m_lpDib = NULL;   m_lpBmpInfo = NULL;m_lpBmpInfoHeader = NULL;m_lpRgbQuad = NULL;m_lpData = NULL;m_lpGradeData = NULL;m_lpColorData = NULL;m_hPalette = NULL;m_bHasRgbQuad = FALSE;m_bValid = FALSE;
}//=======================================================
// 函数功能: 析构函数
// 输入参数: 无
// 返回值:   无
//=======================================================
CDib::~CDib(void)
{// 清理空间Empty();
}//=======================================================
// 函数功能: 从文件加载位图
// 输入参数: lpszPath-待加载位图文件路径
// 返回值:   位图加载结果:TRUE-成功;FALSE-失败
//=======================================================
BOOL CDib::LoadFromFile(LPCTSTR lpszPath)
{// 记录位图文件名strcpy(m_fileName, lpszPath);// 以读模式打开位图文件CFile dibFile;if(!dibFile.Open(m_fileName, CFile::modeRead | CFile::shareDenyWrite)){return FALSE;}// 清理空间Empty();// 读取位图文件头m_lpBmpFileHeader = (LPBITMAPFILEHEADER)new BYTE[sizeof(BITMAPFILEHEADER)];int nCount = dibFile.Read((void *)m_lpBmpFileHeader, sizeof(BITMAPFILEHEADER));if(nCount != sizeof(BITMAPFILEHEADER)) {return FALSE;} // 判断此文件是不是位图文件(“0x4d42”代表“BM”)if(m_lpBmpFileHeader->bfType == 0x4d42){// 是位图文件// 计算除位图文件头的空间大小,并分配空间DWORD dwDibSize = dibFile.GetLength() - sizeof(BITMAPFILEHEADER);m_lpDib = new BYTE[dwDibSize];// 读取除位图文件头的所有数据dibFile.Read(m_lpDib, dwDibSize);// 关闭位图文件dibFile.Close();// 设置位图信息指针m_lpBmpInfo = (LPBITMAPINFO)m_lpDib;// 设置位图信息头指针m_lpBmpInfoHeader = (LPBITMAPINFOHEADER)m_lpDib;// 设置每像素占的位数m_uBitCount = m_lpBmpInfoHeader->biBitCount;// 计算每行像素所占位数m_uLineByte = (GetWidth() * m_uBitCount / 8 + 3) / 4 * 4;// 设置位图颜色表指针m_lpRgbQuad = (LPRGBQUAD)(m_lpDib + m_lpBmpInfoHeader->biSize);// 计算位图颜色m_uNumOfColor = CalcNumOfColor();// 如果位图没有设置位图使用的颜色数,设置它if(m_lpBmpInfoHeader->biClrUsed == 0){m_lpBmpInfoHeader->biClrUsed = m_uNumOfColor;}// 计算颜色表长度m_uRgbQuadLength = m_uNumOfColor * sizeof(RGBQUAD);// 设置位图数据指针m_lpData = m_lpDib + m_lpBmpInfoHeader->biSize + m_uRgbQuadLength;// 判断是否有颜色表if(m_lpRgbQuad == (LPRGBQUAD)m_lpData){m_lpRgbQuad = NULL;    // 将位图颜色表指针置空m_bHasRgbQuad = FALSE; // 无颜色表}else{m_bHasRgbQuad = TRUE;  // 有颜色表MakePalette();         // 根据颜色表生成调色板}        // 设置位图大小m_lpBmpInfoHeader->biSizeImage = GetSize();// 位图有效m_bValid = TRUE;return TRUE;}else{// 不是位图文件m_bValid = FALSE;return FALSE;}     }//=======================================================
// 函数功能: 将位图保存到文件
// 输入参数: lpszPath-位图文件保存路径
// 返回值:   位图保存结果:TRUE-成功;FALSE-失败
//=======================================================
BOOL CDib::SaveToFile(LPCTSTR lpszPath)
{// 记录位图文件名strcpy(m_fileName, lpszPath);// 以写模式打开文件CFile dibFile;if(!dibFile.Open(lpszPath, CFile::modeCreate | CFile::modeReadWrite | CFile::shareExclusive)){return FALSE;}// 填写文件头结构BITMAPFILEHEADER bmpFileHeader;bmpFileHeader.bfType = 0x4d42; // "0x4d42" 代表 "BM"bmpFileHeader.bfSize = 0;bmpFileHeader.bfReserved1 = bmpFileHeader.bfReserved2 = 0;bmpFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)+ m_uRgbQuadLength;	// 将文件头结构写进文件dibFile.Write(m_lpBmpFileHeader, sizeof(BITMAPFILEHEADER));// 将文件信息头结构写进文件dibFile.Write(m_lpBmpInfoHeader, sizeof(BITMAPINFOHEADER));// 如果有颜色表的话,将颜色表写进文件if(m_uRgbQuadLength != 0){dibFile.Write(m_lpRgbQuad, m_uRgbQuadLength);}                                                        // 将位图数据写进文件UINT uDataSize = (GetWidth() * m_uBitCount / 8 + 3) / 4 * 4 * GetHeight();dibFile.Write(m_lpData, uDataSize);// 关闭文件dibFile.Close();return TRUE;
}//=======================================================
// 函数功能: 获取位图文件名
// 输入参数: 无
// 返回值:   LPCTSTR 位图文件名
//=======================================================
LPCTSTR CDib::GetFileName()
{return m_fileName;
}//=======================================================
// 函数功能: 获取位图大小
// 输入参数: 无
// 返回值:   DWORD 位图大小
//=======================================================
DWORD CDib::GetSize()
{if(m_lpBmpInfoHeader->biSizeImage != 0){return m_lpBmpInfoHeader->biSizeImage;}else{DWORD dwWidth = (DWORD)GetWidth();DWORD dwHeight = (DWORD)GetHeight();        return dwWidth * dwHeight;}
}//=======================================================
// 函数功能: 获取位图宽度
// 输入参数: 无
// 返回值:   UINT 位图宽度
//=======================================================
UINT CDib::GetWidth()
{return (UINT)m_lpBmpInfoHeader->biWidth;
}//=======================================================
// 函数功能: 获取位图高度
// 输入参数: 无
// 返回值:   UINT 位图高度
//=======================================================
UINT CDib::GetHeight()
{return (UINT)m_lpBmpInfoHeader->biHeight;
}//=======================================================
// 函数功能: 获取位图的宽度和高度
// 输入参数: 无
// 返回值:   位图的宽度和高度
//=======================================================
CSize CDib::GetDimension()
{return CSize(GetWidth(), GetHeight());
}//=======================================================
// 函数功能: 计算位图颜色数
// 输入参数: 无
// 返回值:   UINT 位图颜色数
//=======================================================
UINT CDib::CalcNumOfColor()
{UINT uNumOfColor;     if ((m_lpBmpInfoHeader->biClrUsed == 0) && (m_lpBmpInfoHeader->biBitCount < 9)){switch (m_lpBmpInfoHeader->biBitCount){case 1: uNumOfColor = 2; break;case 4: uNumOfColor = 16; break;case 8: uNumOfColor = 256;}}else{uNumOfColor = (UINT) m_lpBmpInfoHeader->biClrUsed;}  		return uNumOfColor;}//=======================================================
// 函数功能: 获取像素所占位数
// 输入参数: 无
// 返回值:   像素所占位数
//=======================================================
UINT CDib::GetBitCount()
{return m_uBitCount;
}//=======================================================
// 函数功能: 获取位图颜色数
// 输入参数: 无
// 返回值:   位图颜色数
//=======================================================
UINT CDib::GetNumOfColor()
{return m_uNumOfColor;}//=======================================================
// 函数功能: 获取位图颜色表
// 输入参数: 无
// 返回值:   LPRGBQUAD 位图颜色表指针
//=======================================================
LPRGBQUAD CDib::GetRgbQuad()
{return m_lpRgbQuad;
}//=======================================================
// 函数功能: 获取位图数据
// 输入参数: 无
// 返回值:   LPBYTE 位图数据指针
//=======================================================
LPBYTE CDib::GetData()
{return m_lpData;
}//=======================================================
// 函数功能: 获取灰度位图数据
// 输入参数: 无
// 返回值:   LPBYTE 灰度位图数据指针
//=======================================================
LPBYTE CDib::GetGradeData()
{// 含有颜色表时已是灰度位图if(GetRgbQuad()){m_lpGradeData = m_lpData;}return m_lpGradeData;
}//=======================================================
// 函数功能: 获取彩色位图数据
// 输入参数: 无
// 返回值:   LPBYTE 彩色位图数据指针
//=======================================================
LPBYTE CDib::GetColorData()
{return m_lpColorData;
}//=======================================================
// 函数功能: 根据颜色表生成调色板
// 输入参数: 无
// 返回值:   生成结果:TRUE-成功;FALSE-失败
//=======================================================
BOOL CDib::MakePalette()
{// 如果颜色表长度为0,则不生成逻辑调色板if(m_uRgbQuadLength == 0) {return FALSE;}//删除旧的调色板对象if(m_hPalette != NULL) DeleteObject(m_hPalette);// 申请缓冲区,生成逻辑调色板LPLOGPALETTE lpLogPalette = (LPLOGPALETTE) new BYTE[2 * sizeof(WORD) + m_uRgbQuadLength * sizeof(PALETTEENTRY)];lpLogPalette->palVersion = 0x300;lpLogPalette->palNumEntries = m_uRgbQuadLength;LPRGBQUAD lpRgbQuad = (LPRGBQUAD) m_lpRgbQuad;for(int i = 0; i < m_uRgbQuadLength; i++) {lpLogPalette->palPalEntry[i].peRed = lpRgbQuad->rgbRed;lpLogPalette->palPalEntry[i].peGreen = lpRgbQuad->rgbGreen;lpLogPalette->palPalEntry[i].peBlue = lpRgbQuad->rgbBlue;lpLogPalette->palPalEntry[i].peFlags = 0;lpRgbQuad++;}// 创建逻辑调色板m_hPalette = CreatePalette(lpLogPalette);// 释放缓冲区delete lpLogPalette;return TRUE;
}//=======================================================
// 函数功能: 显示位图
// 输入参数:
//            pDC-设备环境指针
//            origin-显示矩形区域的左上角
//            size-显示矩形区域的尺寸
// 返回值:
//            显示结果:TRUE-成功;FALSE-失败
//=======================================================
BOOL CDib::Draw(CDC *pDC, CPoint origin, CSize size)
{// 旧的调色板句柄HPALETTE hOldPalette = NULL;// 如果位图指针为空,则返回FALSEif(m_lpDib == NULL) {return FALSE;}// 如果位图有调色板,则选进设备环境中if(m_hPalette != NULL) {hOldPalette = SelectPalette(pDC->GetSafeHdc(), m_hPalette, TRUE);}// 设置位图伸缩模式pDC->SetStretchBltMode(COLORONCOLOR);// 将位图在pDC所指向的设备上进行显示StretchDIBits(pDC->GetSafeHdc(), origin.x, origin.y, size.cx, size.cy,0, 0, GetWidth(), GetHeight(), m_lpData, m_lpBmpInfo, DIB_RGB_COLORS, SRCCOPY);// 恢复旧的调色板if(hOldPalette != NULL){SelectPalette(pDC->GetSafeHdc(), hOldPalette, TRUE);}return TRUE;
}//=======================================================
// 函数功能: 获取每行像素所占字节数
// 输入参数: 无
// 返回值:   每行像素所占字节数
//=======================================================
UINT CDib::GetLineByte()
{return m_uLineByte;
}//=======================================================
// 函数功能: 彩色位图转灰度位图
// 输入参数: 无
// 返回值:   转换结果:TRUE-成功;FALSE-失败
//=======================================================
BOOL CDib::RgbToGrade()
{// 颜色表存在时已是灰度图,无须转换,否则需要转换if(GetRgbQuad()){m_lpGradeData = m_lpData;}else{BYTE r, g, b;UINT uHeight = GetHeight();UINT uWidth = GetWidth();UINT uLineByte = GetLineByte();// 如果已分配空间,释放原有空间if((m_lpGradeData != NULL) && (m_lpGradeData != m_lpData)){delete [] m_lpGradeData;}// 重新分配空间m_lpGradeData = (LPBYTE)new BYTE[GetSize()];// 进行转换for(int i = 0; i < uHeight; i++){for(int j = 0; j < uWidth; j++){b = m_lpData[i * m_uLineByte + 3 * j];g = m_lpData[i * m_uLineByte + 3 * j + 1];r = m_lpData[i * m_uLineByte + 3 * j + 2];m_lpGradeData[i * uWidth + j] = (BYTE)(0.3 * r + 0.59 * g + 0.11 * b); }}// 指向转换换后的位图数据m_lpData = m_lpGradeData;// 更新位图头信息// 每像素所占位数m_lpBmpInfoHeader->biBitCount = 8;m_uBitCount = 8;// 每行像素所占字节数m_uLineByte = (GetWidth() * m_uBitCount / 8 + 3) / 4 * 4;}return TRUE;   
}   //=======================================================
// 函数功能: 灰度位图转彩色位图
// 输入参数: 无
// 返回值:   转换结果:TRUE-成功;FALSE-失败
//=======================================================
BOOL CDib::GradeToRgb()
{// 颜色表存在时是灰度图,需转换,否则不需要转换if(GetRgbQuad()){UINT uHeight = GetHeight();UINT uWidth = GetWidth();UINT uLineByte = GetLineByte();// 如果已分配空间,释放原有空间if((m_lpColorData != NULL) && (m_lpColorData != m_lpData)){delete [] m_lpColorData;}// 重新分配空间m_lpColorData = (LPBYTE)new BYTE[GetSize()*3];// 进行转换for(int i = 0; i < uHeight; i++){for(int j = 0; j < uWidth; j++){m_lpColorData[(uHeight - i - 1) * m_uLineByte + 3 * j] = m_lpData[(uHeight - i - 1) * uWidth + i];m_lpColorData[(uHeight - i - 1) * m_uLineByte + 3 * j + 1] = m_lpData[(uHeight - i - 1) * uWidth + i];m_lpColorData[(uHeight - i - 1) * m_uLineByte + 3 * j + 2] = m_lpData[(uHeight - i - 1) * uWidth + i];}}// 指向转换换后的位图数据m_lpData = m_lpColorData;// 更新位图头信息// 每像素所占位数m_lpBmpInfoHeader->biBitCount = 24;m_uBitCount = 24;// 每行像素所占字节数m_uLineByte = (GetWidth() * m_uBitCount / 8 + 3) / 4 * 4;}        return TRUE;   
}   //=======================================================
// 函数功能: 判断是否含有颜色表
// 输入参数: 无
// 返回值:   判断结果:TRUE-含有颜色表;FALSE-不含颜色表
//=======================================================
BOOL CDib::HasRgbQuad()
{return m_bHasRgbQuad;
}//=======================================================
// 函数功能: 判断是否是灰度图
// 输入参数: 无
// 返回值:   判断结果:TRUE-是灰度图;FALSE-是彩色图
//=======================================================
BOOL CDib::IsGrade()
{return (m_uBitCount < 9);
}//=======================================================
// 函数功能: 判断位图是否有效
// 输入参数: 无
// 返回值:   判断结果:TRUE-位图有效;FALSE-位图无效
//=======================================================
BOOL CDib::IsValid()
{return m_bValid;
}//=======================================================
// 函数功能: 清理空间
// 输入参数: 无
// 返回值:   无
//=======================================================
void CDib::Empty()
{// 释放位图文件头指针空间if(m_lpBmpFileHeader != NULL){delete [] m_lpBmpFileHeader;}// 释放灰度位图数据空间if((m_lpGradeData != NULL) && (m_lpGradeData != m_lpData)){delete [] m_lpGradeData;}// 释放彩色位图数据空间if((m_lpColorData != NULL) && (m_lpColorData != m_lpData)){delete [] m_lpColorData;}// 释放位图指针空间if(m_lpDib != NULL){delete [] m_lpDib;m_lpBmpInfo = NULL;m_lpBmpInfoHeader = NULL;m_lpRgbQuad = NULL;m_lpData = NULL;           }       // 释放调色板if(m_hPalette != NULL){DeleteObject(m_hPalette);m_hPalette = NULL;}    // 设置不含颜色表m_bHasRgbQuad = FALSE;// 设置位图无效m_bValid = FALSE;}  

EdgeDetection.h

#pragma once
//边缘检测类
#include "Dib.h"class CEdgeDetection
{
public:CEdgeDetection(CDib *pDib);void Roberts(void);void Template(LPBYTE lpData, int nLineByte, int nWidth, int nHeight, int nTemH, int nTemW, int nTemCX, int nTemCY, float *fpArray, float fCoef);void Sobel(void);void Prewitt(void);void Laplacian(void);void GuassLaplacian(void);void Krisch(void);
public:~CEdgeDetection(void);
private:CDib *m_pDib;
};

EdgeDetection.cpp

#include "StdAfx.h"
#include "EdgeDetection.h"
#include "math.h"CEdgeDetection::CEdgeDetection(CDib *pDib)
{m_pDib = pDib;
}CEdgeDetection::~CEdgeDetection(void)
{
}//=======================================================
// 函数功能: Roberts边缘检测算子
// 输入参数: void
// 返回值:   void 
//=======================================================
void CEdgeDetection::Roberts(void)
{// 循环变量int i, j;// 原图像数据区指针LPBYTE lpData;lpData = m_pDib->GetData();// 图像每行像素所占的字节数int nLineByte = m_pDib->GetLineByte();// 图像的宽度int nWidth = m_pDib->GetWidth();// 图像的高度int nHeight = m_pDib->GetHeight();// 新图像缓冲区的指针LPBYTE lpTemp; lpTemp = new BYTE[nLineByte * nHeight];// 初始化新分配的内存,设定初始值为255memset(lpTemp, 255, nLineByte * nHeight);// Roberts算子int pixel[4]; // 由于使用2*2的模板,为防止越界,不处理最上边和最右边的边界像素for(j = 0; j < nHeight - 1; j ++)for(i = 0; i < nWidth - 1; i ++){//生成Roberts算子pixel[0] = lpData[j * nLineByte + i];pixel[1] = lpData[j * nLineByte + i + 1];pixel[2] = lpData[(j + 1) * nLineByte + i];pixel[3] = lpData[(j + 1) * nLineByte + i + 1];// 处理当前像素lpTemp[j * nLineByte + i] = sqrt(double ( (pixel[0] - pixel[3]) * (pixel[0] - pixel[3])+ (pixel[1] - pixel[2]) * (pixel[1] - pixel[2]) ) );lpTemp[j * nLineByte + i] = 255 - lpTemp[j * nLineByte + i];}// 将处理后的新图像复制到原图像中memcpy(lpData,lpTemp, nLineByte * nHeight);// 释放内存delete [] lpTemp;
}//=======================================================
// 函数功能: 灰度模板
// 输入参数: LPBYTE lpData: 指向原图像数据区指针 
//            int nLineByte: 原图像每行像素所占的字节数
//            int nWidth: 原图像宽度                                    
//            int nHeight: 原图像高度                                  
//            int nTemH: 模板高度                                     
//            int nTemW: 模板宽度                                     
//            int nTemCX: 模板中心元素的X坐标(<nTemW-1)               
//            int nTemCY: 模板的中心元素的Y坐标(<nTemH-1)               
//            float *fpArray: 指向模板数组的指针                      
//            float fCoef:模板系数         
// 返回值:   void 
//=======================================================
void CEdgeDetection::Template(LPBYTE lpData, int nLineByte, int nWidth, int nHeight, int nTemH, int nTemW, int nTemCX, int nTemCY, float *fpArray, float fCoef)
{   // 循环变量int i, j, k, l; // 新图像缓冲区的指针LPBYTE lpTemp; lpTemp = new BYTE[nLineByte * nHeight];// 初始化新分配的内存,设定初始值为255memset(lpTemp, 255, nLineByte * nHeight);// 像素值计算结果float fResult; for(j = nTemCY; j < nHeight - nTemH + nTemCY + 1; j ++)for(i = nTemCX; i < nWidth - nTemW + nTemCX + 1; i ++){// 计算当前像素值fResult = 0;for(k = 0; k < nTemH; k ++)for(l = 0; l < nTemW; l ++)// 卷积运算fResult += lpData[(j - nTemCY + k) * nLineByte + (i - nTemCX + l)]* fpArray[k * nTemW + l];//用系数乘以当前像素值计算结果fResult *= fCoef;//取绝对值fResult = (float) fabs(fResult);// 判断是否超过255if(fResult > 255)// 若超过255,在新图像当前像素位置直接赋值为255lpTemp[j * nLineByte + i] = 255;else// 未超过255,在新图像当前像素位置赋值为计算结果lpTemp[j * nLineByte + i] = (int) (fResult + 0.5);}// 将处理后的新图像复制到原图像中memcpy(lpData,lpTemp, nLineByte * nHeight);// 释放内存delete [] lpTemp;
}//=======================================================
// 函数功能: Sobel边缘检测算子
// 输入参数: void
// 返回值:   void 
//=======================================================
void CEdgeDetection::Sobel()
{// 原图像数据区指针LPBYTE lpData;lpData = m_pDib->GetData();// 图像每行像素所占的字节数int nLineByte = m_pDib->GetLineByte();// 图像的宽度int nWidth = m_pDib->GetWidth();// 图像的高度int nHeight = m_pDib->GetHeight();// 模板宽度和高度int nTemW, nTemH; // 模板系数float fCoef; //模板中心元素的X坐标和Y坐标int nTemCX, nTemCY;  //模板数组float arTemplate[9]; //在此添加关键代码}//=======================================================
// 函数功能: Prewitt边缘检测算子
// 输入参数: void
// 返回值:   void 
//=======================================================
void CEdgeDetection::Prewitt(void)
{// 原图像数据区指针LPBYTE lpData;lpData = m_pDib->GetData();// 图像每行像素所占的字节数int nLineByte = m_pDib->GetLineByte();// 图像的宽度int nWidth = m_pDib->GetWidth();// 图像的高度int nHeight = m_pDib->GetHeight();// 模板宽度和高度int nTemW, nTemH; // 模板系数float fCoef; //模板中心元素的X坐标和Y坐标int nTemCX, nTemCY;  //模板数组float arTemplate[9]; //在此添加关键程序}//=======================================================
// 函数功能: Laplacian边缘检测算子
// 输入参数: void
// 返回值:   void 
//=======================================================
void CEdgeDetection::Laplacian(void)
{// 原图像数据区指针LPBYTE lpData;lpData = m_pDib->GetData();// 图像每行像素所占的字节数int nLineByte = m_pDib->GetLineByte();// 图像的宽度int nWidth = m_pDib->GetWidth();// 图像的高度int nHeight = m_pDib->GetHeight();// 模板宽度和高度int nTemW, nTemH; // 模板系数float fCoef; //模板中心元素的X坐标和Y坐标int nTemCX, nTemCY;  //模板数组float arTemplate[9]; //在此添加关键代码}//=======================================================
// 函数功能: GuassLaplacian边缘检测算子
// 输入参数: void
// 返回值:   void 
//=======================================================
void CEdgeDetection::GuassLaplacian(void)
{// 原图像数据区指针LPBYTE lpData;lpData = m_pDib->GetData();// 图像每行像素所占的字节数int nLineByte = m_pDib->GetLineByte();// 图像的宽度int nWidth = m_pDib->GetWidth();// 图像的高度int nHeight = m_pDib->GetHeight();// 模板宽度和高度int nTemW, nTemH; // 模板系数float fCoef; //模板中心元素的X坐标和Y坐标int nTemCX, nTemCY;  //模板数组float arTemplate[25]; // 新图像缓冲区的指针LPBYTE lpTemp; lpTemp = new BYTE[nLineByte * nHeight];// 初始化新分配的内存,复制原图像memcpy(lpTemp, lpData, nLineByte * nHeight);// 设置GuassLaplacian模板的参数nTemW = 5;nTemH = 5;fCoef = 0.25;nTemCX = 4;nTemCY = 4;arTemplate[0] = -2.0;arTemplate[1] = -4.0;arTemplate[2] = -4.0;arTemplate[3] = -4.0;arTemplate[4] = -2.0;arTemplate[5] = -4.0;arTemplate[6] = 0.0;arTemplate[7] = 8.0;arTemplate[8] = 0.0;arTemplate[9] = -4.0;arTemplate[10] = -4.0;arTemplate[11] = 8.0;arTemplate[12] = 24.0;arTemplate[13] = 8.0;arTemplate[14] = -4.0;arTemplate[15] = -4.0;arTemplate[16] = 0.0;arTemplate[17] = 8.0;arTemplate[18] = 0.0;arTemplate[19] = -4.0;arTemplate[20] = -2.0;arTemplate[21] = -4.0;arTemplate[22] = -4.0;arTemplate[23] = -4.0;arTemplate[24] = -2.0;// 调用Template()函数Template(lpTemp, nLineByte, nWidth, nHeight, nTemH, nTemW, nTemCX, nTemCY, arTemplate, fCoef); // 将缓存图像复制到原图像中memcpy(lpData, lpTemp, nLineByte * nHeight);// 删除缓冲区delete  [] lpTemp;
}//=======================================================
// 函数功能: Krisch边缘检测算子
// 输入参数: void
// 返回值:   void 
//=======================================================
void CEdgeDetection::Krisch(void)
{// 原图像数据区指针LPBYTE lpData;lpData = m_pDib->GetData();// 图像每行像素所占的字节数int nLineByte = m_pDib->GetLineByte();// 图像的宽度int nWidth = m_pDib->GetWidth();// 图像的高度int nHeight = m_pDib->GetHeight(); // 模板宽度和高度int nTemW, nTemH; // 模板系数float fCoef; //模板中心元素的X坐标和Y坐标int nTemCX, nTemCY;  //模板数组float arTemplate[9]; // 两幅新图像缓冲区的指针LPBYTE lpTemp1, lpTemp2; lpTemp1 = new BYTE[nLineByte * nHeight];lpTemp2 = new BYTE[nLineByte * nHeight];// 初始化新分配的内存,复制原图像memcpy(lpTemp1, lpData, nLineByte * nHeight);memcpy(lpTemp2, lpData, nLineByte * nHeight);// 设置Krisch模板一的参数nTemW = 3;nTemH = 3;fCoef = 0.5;nTemCX = 1;nTemCY = 1;arTemplate[0] = 5.0;arTemplate[1] = 5.0;arTemplate[2] = 5.0;arTemplate[3] = -3.0;arTemplate[4] = 0.0;arTemplate[5] = -3.0;arTemplate[6] = -3.0;arTemplate[7] = -3.0;arTemplate[8] = -3.0;// 调用Template()函数Template(lpTemp1, nLineByte, nWidth, nHeight, nTemH, nTemW, nTemCX, nTemCY, arTemplate, fCoef); // 设置Krisch模板二的参数arTemplate[0] = -3.0;arTemplate[1] = 5.0;arTemplate[2] = 5.0;arTemplate[3] = -3.0;arTemplate[4] = 0.0;arTemplate[5] = 5.0;arTemplate[6] = -3.0;arTemplate[7] = -3.0;arTemplate[8] = -3.0;// 调用Template()函数Template(lpTemp2, nLineByte, nWidth, nHeight, nTemH, nTemW, nTemCX, nTemCY, arTemplate, fCoef);// 取两幅缓存图像对应像素的最大值,并存放在第一个缓存图像中for(int j = 0; j < nHeight; j ++)for(int i = 0; i < nWidth; i ++)if( lpTemp2[j * nLineByte + i] > lpTemp1[j * nLineByte + i] )lpTemp1[j * nLineByte + i] = lpTemp2[j * nLineByte + i];// 将原图像复制到第二个缓存图像中memcpy(lpTemp2, lpData, nLineByte * nHeight);// 设置Krisch模板三的参数arTemplate[0] = -3.0;arTemplate[1] = -3.0;arTemplate[2] = 5.0;arTemplate[3] = -3.0;arTemplate[4] = 0.0;arTemplate[5] = 5.0;arTemplate[6] = -3.0;arTemplate[7] = -3.0;arTemplate[8] = 5.0;// 调用Template()函数Template(lpTemp2, nLineByte, nWidth, nHeight, nTemH, nTemW, nTemCX, nTemCY, arTemplate, fCoef);// 取两幅缓存图像对应像素的最大值,并存放在第一个缓存图像中for(int j = 0; j < nHeight; j ++)for(int i = 0; i < nWidth; i ++)if( lpTemp2[j * nLineByte + i] > lpTemp1[j * nLineByte + i] )lpTemp1[j * nLineByte + i] = lpTemp2[j * nLineByte + i];// 将原图像复制到第二个缓存图像中memcpy(lpTemp2, lpData, nLineByte * nHeight);// 设置Krisch模板四的参数arTemplate[0] = -3.0;arTemplate[1] = -3.0;arTemplate[2] = -3.0;arTemplate[3] = -3.0;arTemplate[4] = 0.0;arTemplate[5] = 5.0;arTemplate[6] = -3.0;arTemplate[7] = 5.0;arTemplate[8] = 5.0;// 调用Template()函数Template(lpTemp2, nLineByte, nWidth, nHeight, nTemH, nTemW, nTemCX, nTemCY, arTemplate, fCoef);// 取两幅缓存图像对应像素的最大值,并存放在第一个缓存图像中for(int j = 0; j < nHeight; j ++)for(int i = 0; i < nWidth; i ++)if( lpTemp2[j * nLineByte + i] > lpTemp1[j * nLineByte + i] )lpTemp1[j * nLineByte + i] = lpTemp2[j * nLineByte + i];// 将原图像复制到第二个缓存图像中memcpy(lpTemp2, lpData, nLineByte * nHeight);// 设置Krisch模板五的参数arTemplate[0] = -3.0;arTemplate[1] = -3.0;arTemplate[2] = -3.0;arTemplate[3] = -3.0;arTemplate[4] = 0.0;arTemplate[5] = -3.0;arTemplate[6] = 5.0;arTemplate[7] = 5.0;arTemplate[8] = 5.0;// 调用Template()函数Template(lpTemp2, nLineByte, nWidth, nHeight, nTemH, nTemW, nTemCX, nTemCY, arTemplate, fCoef);// 取两幅缓存图像对应像素的最大值,并存放在第一个缓存图像中for(int j = 0; j < nHeight; j ++)for(int i = 0; i < nWidth; i ++)if( lpTemp2[j * nLineByte + i] > lpTemp1[j * nLineByte + i] )lpTemp1[j * nLineByte + i] = lpTemp2[j * nLineByte + i];// 将原图像复制到第二个缓存图像中memcpy(lpTemp2, lpData, nLineByte * nHeight);// 设置Krisch模板六的参数arTemplate[0] = -3.0;arTemplate[1] = -3.0;arTemplate[2] = -3.0;arTemplate[3] = 5.0;arTemplate[4] = 0.0;arTemplate[5] = -3.0;arTemplate[6] = 5.0;arTemplate[7] = 5.0;arTemplate[8] = -3.0;// 调用Template()函数Template(lpTemp2, nLineByte, nWidth, nHeight, nTemH, nTemW, nTemCX, nTemCY, arTemplate, fCoef);// 取两幅缓存图像对应像素的最大值,并存放在第一个缓存图像中for(int j = 0; j < nHeight; j ++)for(int i = 0; i < nWidth; i ++)if( lpTemp2[j * nLineByte + i] > lpTemp1[j * nLineByte + i] )lpTemp1[j * nLineByte + i] = lpTemp2[j * nLineByte + i];// 将原图像复制到第二个缓存图像中memcpy(lpTemp2, lpData, nLineByte * nHeight);// 设置Krisch模板七的参数arTemplate[0] = 5.0;arTemplate[1] = -3.0;arTemplate[2] = -3.0;arTemplate[3] = 5.0;arTemplate[4] = 0.0;arTemplate[5] = -3.0;arTemplate[6] = 5.0;arTemplate[7] = -3.0;arTemplate[8] = -3.0;// 调用Template()函数Template(lpTemp2, nLineByte, nWidth, nHeight, nTemH, nTemW, nTemCX, nTemCY, arTemplate, fCoef);// 取两幅缓存图像对应像素的最大值,并存放在第一个缓存图像中for(int j = 0; j < nHeight; j ++)for(int i = 0; i < nWidth; i ++)if( lpTemp2[j * nLineByte + i] > lpTemp1[j * nLineByte + i] )lpTemp1[j * nLineByte + i] = lpTemp2[j * nLineByte + i];// 将原图像复制到第二个缓存图像中memcpy(lpTemp2, lpData, nLineByte * nHeight);// 设置Krisch模板八的参数arTemplate[0] = 5.0;arTemplate[1] = 5.0;arTemplate[2] = -3.0;arTemplate[3] = 5.0;arTemplate[4] = 0.0;arTemplate[5] = -3.0;arTemplate[6] = -3.0;arTemplate[7] = -3.0;arTemplate[8] = -3.0;// 调用Template()函数Template(lpTemp2, nLineByte, nWidth, nHeight, nTemH, nTemW, nTemCX, nTemCY, arTemplate, fCoef);// 取两幅缓存图像对应像素的最大值,并存放在第一个缓存图像中for(int j = 0; j < nHeight; j ++)for(int i = 0; i < nWidth; i ++)if( lpTemp2[j * nLineByte + i] > lpTemp1[j * nLineByte + i] )lpTemp1[j * nLineByte + i] = lpTemp2[j * nLineByte + i];// 将第一个缓存图像复制到原图像中memcpy(lpData, lpTemp1, nLineByte * nHeight);// 删除缓冲区delete  [] lpTemp1;delete  [] lpTemp2;
}

Threshold.h

#pragma once#include "Dib.h"class CThreshold
{
public:CThreshold();CThreshold(CDib *pDib);
public:~CThreshold(void);
public:void AdaptiveThreshold(void);void OtusThreshold(void);
private:CDib * m_pDib; 
};

Threshold.cpp

#include "StdAfx.h"
#include "Threshold.h"
#include "math.h"CThreshold::CThreshold()
{
}CThreshold::CThreshold(CDib *pDib)
{m_pDib = pDib;
}CThreshold::~CThreshold(void)
{
}//=======================================================
// 函数功能: 最大方差阈值分割
// 输入参数: 无
// 返回值:   无
//=======================================================
void CThreshold::OtusThreshold(void)
{// 循环变量int i, j;// 原图数据区指针LPBYTE p_data;p_data = m_pDib->GetData();// 图像每行像素所占的字节数int nLineByte = m_pDib->GetLineByte();// 图像的宽度int nWidth = m_pDib->GetWidth();// 图像的高度int nHeight = m_pDib->GetHeight();// 灰度直方图数组,并初始化int nGrayHistogram[256];memset(nGrayHistogram, 0, sizeof(nGrayHistogram));// 统计各个灰度级对应的像素个数,并存放到灰度直方图数组中int nPixel;for (j = 0; j < nHeight; j ++)for (i = 0; i < nWidth; i ++){// 获取当前像素点的灰度值nPixel = p_data[nLineByte * j + i];	// 对灰度值统计计数nGrayHistogram[nPixel] ++;		}// c0组和c1组的均值float u0, u1;// c0组和c1组的概率float w0, w1;// c0组的像素总数int nCount0;// 阈值和最佳阈值(对应方差最大时的阈值)int nT, nBestT;// 方差和最大方差float fVaria, fMaxVaria = 0;// 统计直方图中像素点的总数,并存放到nSum中int nSum=0;for(i = 0; i < 256; i ++)nSum += nGrayHistogram[i];// 令阈值nT从0遍历到255for(nT = 0; nT < 256; nT ++){// 当阈值为nT时,计算c0组的均值和概率u0 = 0;nCount0 = 0;for(i = 0; i <= nT; i++){u0 += i * nGrayHistogram[i];nCount0 += nGrayHistogram[i];}u0 /= nCount0;w0 = (float) nCount0 / nSum;// 当阈值为nT时,计算c1组的均值和概率u1 = 0;for(i = nT+1; i < 256; i ++)u1 += i * nGrayHistogram[i];u1 /= (nSum - nCount0);w1 = 1 - w0;// 计算两组间的方差fVaria = w0 * w1 * (u0 - u1) * (u0 - u1);// 记录最大方差和最佳阈值if(fVaria > fMaxVaria){fMaxVaria = fVaria;nBestT = nT;}}// 利用最佳阈值对原图像作分割处理for(j = 0; j < nHeight; j ++)for(i = 0; i < nWidth; i ++){if(p_data[j * nLineByte + i] < nBestT)p_data[j * nLineByte + i] = 0;elsep_data[j * nLineByte + i] = 255;}
}//=======================================================
// 函数功能: 自适应阈值分割
// 输入参数: 无
// 返回值:   无
//=======================================================
void CThreshold::AdaptiveThreshold(void)
{// 循环变量int i,j;// 原图像数据区指针LPBYTE p_data;p_data = m_pDib->GetData();// 图像每行像素所占的字节数int nLineByte = m_pDib->GetLineByte();// 图像的宽度int nWidth = m_pDib->GetWidth();// 图像的高度int nHeight = m_pDib->GetHeight();// 局部阈值int nThreshold[2][2];// 子图像的灰度平均值int nAvgValue;// 对左上图像逐点扫描,计算该子图像的灰度平均值nAvgValue = 0;for(j = nHeight / 2; j < nHeight; j ++)for(i = 0; i < nWidth / 2; i ++)nAvgValue += p_data[j * nLineByte + i];nAvgValue /= ((nHeight / 2) * (nLineByte / 2));// 设置阈值为子图像的平均值nThreshold[0][0] = nAvgValue;// 对左上图像逐点扫描并进行阈值分割for(j = nHeight / 2; j < nHeight; j ++)for(i = 0; i < nWidth / 2; i ++){if(p_data[j * nLineByte + i] < nThreshold[0][0])p_data[j * nLineByte + i] = 0;elsep_data[j * nLineByte + i] = 255;}// 对右上图像逐点扫描,计算该子图像的灰度平均值nAvgValue = 0;for(j = nHeight / 2; j < nHeight; j ++)for(i = nWidth / 2; i < nWidth; i ++)nAvgValue += p_data[j * nLineByte + i];nAvgValue /= ((nHeight / 2) * (nLineByte / 2));// 设置阈值为子图像的平均值nThreshold[0][1] = nAvgValue;// 对右上图像逐点扫描并进行阈值分割for(j = nHeight / 2; j < nHeight; j ++)for(i = nWidth / 2; i < nWidth; i ++){if(p_data[j * nLineByte + i] < nThreshold[0][0])p_data[j * nLineByte + i] = 0;elsep_data[j * nLineByte + i] = 255;}// 对左下图像逐点扫描,计算该子图像的灰度平均值nAvgValue = 0;for(j = 0; j < nHeight / 2; j ++)for(i = 0; i < nWidth / 2; i ++)nAvgValue += p_data[j * nLineByte + i];nAvgValue /= ((nHeight / 2) * (nLineByte / 2));// 设置阈值为子图像的平均值nThreshold[1][0] = nAvgValue;// 对左下图像逐点扫描并进行阈值分割for(j = 0; j < nHeight / 2; j ++)for(i = 0; i < nWidth / 2; i ++){if(p_data[j * nLineByte + i] < nThreshold[0][0])p_data[j * nLineByte + i] = 0;elsep_data[j * nLineByte + i] = 255;}// 对右下图像逐点扫描,计算该子图像的灰度平均值nAvgValue = 0;for(j = 0; j < nHeight / 2; j ++)for(i = nWidth / 2; i < nWidth; i ++)nAvgValue += p_data[j * nLineByte + i];nAvgValue /= ((nHeight / 2) * (nLineByte / 2));// 设置阈值为子图像的平均值nThreshold[1][1] = nAvgValue;// 对右下下图像逐点扫描并进行阈值分割for(j = 0; j < nHeight / 2; j ++)for(i = nWidth / 2; i < nWidth;i ++){if(p_data[j * nLineByte + i] < nThreshold[0][0])p_data[j * nLineByte + i] = 0;elsep_data[j * nLineByte + i] = 255;}
}

基于单文档的图像分割View.h


// 基于单文档的图像分割View.h : C基于单文档的图像分割View 类的接口
//#pragma once
#include "Dib.h"  内容: 设备无关位图类-头文件class C基于单文档的图像分割View : public CView
{
protected: // 仅从序列化创建C基于单文档的图像分割View();DECLARE_DYNCREATE(C基于单文档的图像分割View)// 特性
public:C基于单文档的图像分割Doc* GetDocument() const;// 操作
public:// 重写
public:virtual void OnDraw(CDC* pDC);  // 重写以绘制该视图virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
protected:virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);// 实现
public:virtual ~C基于单文档的图像分割View();
#ifdef _DEBUGvirtual void AssertValid() const;virtual void Dump(CDumpContext& dc) const;
#endifprotected:// 生成的消息映射函数
protected:DECLARE_MESSAGE_MAP()
public:CDib m_PhotoImage;//照片图像BOOL flag;//打开照片图像标记变量  要在默认afx_msg void OnOpenImage();afx_msg void OnRoberts();afx_msg void OnSobel();afx_msg void OnPrewitt();afx_msg void OnKrisch();afx_msg void OnLaplacian();afx_msg void OnGuassLaplacian();afx_msg void OnOtusthreshold();afx_msg void OnAdapthresh();
};#ifndef _DEBUG  // 基于单文档的图像分割View.cpp 中的调试版本
inline C基于单文档的图像分割Doc* C基于单文档的图像分割View::GetDocument() const{ return reinterpret_cast<C基于单文档的图像分割Doc*>(m_pDocument); }
#endif

基于单文档的图像分割View.cpp


// 基于单文档的图像分割View.cpp : C基于单文档的图像分割View 类的实现
//#include "stdafx.h"
// SHARED_HANDLERS 可以在实现预览、缩略图和搜索筛选器句柄的
// ATL 项目中进行定义,并允许与该项目共享文档代码。
#ifndef SHARED_HANDLERS
#include "基于单文档的图像分割.h"
#endif#include "基于单文档的图像分割Doc.h"
#include "基于单文档的图像分割View.h"
#include "EdgeDetection.h"边缘检测类
#include "Threshold.h"//阈值分割法类#ifdef _DEBUG
#define new DEBUG_NEW
#endif// C基于单文档的图像分割ViewIMPLEMENT_DYNCREATE(C基于单文档的图像分割View, CView)BEGIN_MESSAGE_MAP(C基于单文档的图像分割View, CView)// 标准打印命令ON_COMMAND(ID_FILE_PRINT, &CView::OnFilePrint)ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint)ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CView::OnFilePrintPreview)ON_COMMAND(ID_OPEN_IMAGE, &C基于单文档的图像分割View::OnOpenImage)ON_COMMAND(ID_ROBERTS, &C基于单文档的图像分割View::OnRoberts)ON_COMMAND(ID_SOBEL, &C基于单文档的图像分割View::OnSobel)ON_COMMAND(ID_PREWITT, &C基于单文档的图像分割View::OnPrewitt)ON_COMMAND(ID_KRISCH, &C基于单文档的图像分割View::OnKrisch)ON_COMMAND(ID_LAPLACIAN, &C基于单文档的图像分割View::OnLaplacian)ON_COMMAND(ID_GUASS_LAPLACIAN, &C基于单文档的图像分割View::OnGuassLaplacian)ON_COMMAND(ID_OTUSTHRESHOLD, &C基于单文档的图像分割View::OnOtusthreshold)ON_COMMAND(ID_ADAPTHRESH, &C基于单文档的图像分割View::OnAdapthresh)
END_MESSAGE_MAP()// C基于单文档的图像分割View 构造/析构C基于单文档的图像分割View::C基于单文档的图像分割View()
{// TODO:  在此处添加构造代码flag = FALSE;//初始化标志位}C基于单文档的图像分割View::~C基于单文档的图像分割View()
{
}BOOL C基于单文档的图像分割View::PreCreateWindow(CREATESTRUCT& cs)
{// TODO:  在此处通过修改//  CREATESTRUCT cs 来修改窗口类或样式return CView::PreCreateWindow(cs);
}// C基于单文档的图像分割View 绘制void C基于单文档的图像分割View::OnDraw(CDC* /*pDC*/)
{C基于单文档的图像分割Doc* pDoc = GetDocument();ASSERT_VALID(pDoc);if (!pDoc)return;// TODO:  在此处为本机数据添加绘制代码
}// C基于单文档的图像分割View 打印BOOL C基于单文档的图像分割View::OnPreparePrinting(CPrintInfo* pInfo)
{// 默认准备return DoPreparePrinting(pInfo);
}void C基于单文档的图像分割View::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{// TODO:  添加额外的打印前进行的初始化过程
}void C基于单文档的图像分割View::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{// TODO:  添加打印后进行的清理过程
}// C基于单文档的图像分割View 诊断#ifdef _DEBUG
void C基于单文档的图像分割View::AssertValid() const
{CView::AssertValid();
}void C基于单文档的图像分割View::Dump(CDumpContext& dc) const
{CView::Dump(dc);
}C基于单文档的图像分割Doc* C基于单文档的图像分割View::GetDocument() const // 非调试版本是内联的
{ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(C基于单文档的图像分割Doc)));return (C基于单文档的图像分割Doc*)m_pDocument;
}
#endif //_DEBUG// C基于单文档的图像分割View 消息处理程序void C基于单文档的图像分割View::OnOpenImage()
{// TODO:  在此添加命令处理程序代码// 本函数功能是打开并显示照片图像CString  filename;CFileDialog dlg(TRUE, _T("BMP"), _T("*.BMP"), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, _T("位图文件(*.BMP)|*.BMP|"));if (IDOK == dlg.DoModal())filename.Format("%s", dlg.GetPathName());m_PhotoImage.LoadFromFile(filename);//打开照片图像flag = TRUE;//照片图像打开后,将标记变量置为真//显示图像CPoint point;CSize size;point.x = 0;point.y = 0;LONG lWidth = m_PhotoImage.GetWidth();    //获得灰度图像的宽度LONG lHeight = m_PhotoImage.GetHeight();  //获得灰度图像的高度size.cx = lWidth;size.cy = lHeight;CDC *pDC = GetDC();m_PhotoImage.Draw(pDC, point, size);}//Roberts算子 响应事件函数
void C基于单文档的图像分割View::OnRoberts()
{// TODO:  在此添加命令处理程序代码//如果之前没加载图像,将在这里提示if (flag == FALSE){AfxMessageBox("请先加载要处理的照片图像!");return;}CPoint point;CSize size;point.x = 0;point.y = 0;LONG lWidth = m_PhotoImage.GetWidth();    //获得灰度图像的宽度LONG lHeight = m_PhotoImage.GetHeight();  //获得灰度图像的高度size.cx = lWidth;size.cy = lHeight;CDC *pDC = GetDC();m_PhotoImage.Draw(pDC, point, size);//绘制处理前的图像if (m_PhotoImage.IsValid()){if (!m_PhotoImage.IsGrade()){AfxMessageBox("本程序只支持灰度位图!");return;}else{CEdgeDetection edgeDetection(&m_PhotoImage);edgeDetection.Roberts();//Invalidate();CPoint point1;point1.x = lWidth + 20;  //+20是为了让两个图像显示时有个间隙point1.y = 0;m_PhotoImage.Draw(pDC, point1, size);//绘制处理后的图像}}
}//Sobel算子 响应事件函数
void C基于单文档的图像分割View::OnSobel()
{// TODO:  在此添加命令处理程序代码//如果之前没加载图像,将在这里提示if (flag == FALSE){AfxMessageBox("请先加载要处理的照片图像!");return;}CPoint point;CSize size;point.x = 0;point.y = 0;LONG lWidth = m_PhotoImage.GetWidth();    //获得灰度图像的宽度LONG lHeight = m_PhotoImage.GetHeight();  //获得灰度图像的高度size.cx = lWidth;size.cy = lHeight;CDC *pDC = GetDC();m_PhotoImage.Draw(pDC, point, size);//绘制处理前的图像//CSegmentDoc *pDoc = GetDocument();//CDib *pDib = pDoc->GetDib();if (m_PhotoImage.IsValid()){if (!m_PhotoImage.IsGrade()){AfxMessageBox("本程序只支持灰度位图!");return;}else{CEdgeDetection edgeDetection(&m_PhotoImage);edgeDetection.Sobel();//Invalidate();CPoint point1;point1.x = lWidth + 20;  //+20是为了让两个图像显示时有个间隙point1.y = 0;m_PhotoImage.Draw(pDC, point1, size);//绘制处理后的图像}}
}//Prewitt算子 响应事件函数
void C基于单文档的图像分割View::OnPrewitt()
{// TODO:  在此添加命令处理程序代码//如果之前没加载图像,将在这里提示if (flag == FALSE){AfxMessageBox("请先加载要处理的照片图像!");return;}CPoint point;CSize size;point.x = 0;point.y = 0;LONG lWidth = m_PhotoImage.GetWidth();    //获得灰度图像的宽度LONG lHeight = m_PhotoImage.GetHeight();  //获得灰度图像的高度size.cx = lWidth;size.cy = lHeight;CDC *pDC = GetDC();m_PhotoImage.Draw(pDC, point, size);//绘制处理前的图像//CSegmentDoc *pDoc = GetDocument();//CDib *pDib = pDoc->GetDib();if (m_PhotoImage.IsValid()){if (!m_PhotoImage.IsGrade()){AfxMessageBox("本程序只支持灰度位图!");return;}else{CEdgeDetection edgeDetection(&m_PhotoImage);edgeDetection.Prewitt();//Invalidate();CPoint point1;point1.x = lWidth + 20;  //+20是为了让两个图像显示时有个间隙point1.y = 0;m_PhotoImage.Draw(pDC, point1, size);//绘制处理后的图像}}
}//Krisch算子 响应事件函数
void C基于单文档的图像分割View::OnKrisch()
{//Krisch算子 响应事件函数// TODO:  在此添加命令处理程序代码//如果之前没加载图像,将在这里提示if (flag == FALSE){AfxMessageBox("请先加载要处理的照片图像!");return;}CPoint point;CSize size;point.x = 0;point.y = 0;LONG lWidth = m_PhotoImage.GetWidth();    //获得灰度图像的宽度LONG lHeight = m_PhotoImage.GetHeight();  //获得灰度图像的高度size.cx = lWidth;size.cy = lHeight;CDC *pDC = GetDC();m_PhotoImage.Draw(pDC, point, size);//绘制处理前的图像//CSegmentDoc *pDoc = GetDocument();//CDib *pDib = pDoc->GetDib();if (m_PhotoImage.IsValid()){if (!m_PhotoImage.IsGrade()){AfxMessageBox("本程序只支持灰度位图!");return;}else{CEdgeDetection edgeDetection(&m_PhotoImage);edgeDetection.Krisch();//Invalidate();CPoint point1;point1.x = lWidth + 20;  //+20是为了让两个图像显示时有个间隙point1.y = 0;m_PhotoImage.Draw(pDC, point1, size);//绘制处理后的图像}}
}//Laplacian算子 响应事件函数
void C基于单文档的图像分割View::OnLaplacian()
{// TODO:  在此添加命令处理程序代码//Laplacian算子 响应事件函数//如果之前没加载图像,将在这里提示if (flag == FALSE){AfxMessageBox("请先加载要处理的照片图像!");return;}CPoint point;CSize size;point.x = 0;point.y = 0;LONG lWidth = m_PhotoImage.GetWidth();    //获得灰度图像的宽度LONG lHeight = m_PhotoImage.GetHeight();  //获得灰度图像的高度size.cx = lWidth;size.cy = lHeight;CDC *pDC = GetDC();m_PhotoImage.Draw(pDC, point, size);//绘制处理前的图像//CSegmentDoc *pDoc = GetDocument();//CDib *pDib = pDoc->GetDib();if (m_PhotoImage.IsValid()){if (!m_PhotoImage.IsGrade()){AfxMessageBox("本程序只支持灰度位图!");return;}else{CEdgeDetection edgeDetection(&m_PhotoImage);edgeDetection.Laplacian();//Invalidate();CPoint point1;point1.x = lWidth + 20;  //+20是为了让两个图像显示时有个间隙point1.y = 0;m_PhotoImage.Draw(pDC, point1, size);//绘制处理后的图像}}
}//Guass - Laplacian算子 响应事件函数
void C基于单文档的图像分割View::OnGuassLaplacian()
{// TODO:  在此添加命令处理程序代码//Guass - Laplacian算子 响应事件函数if (flag == FALSE){AfxMessageBox("请先加载要处理的照片图像!");return;}CPoint point;CSize size;point.x = 0;point.y = 0;LONG lWidth = m_PhotoImage.GetWidth();    //获得灰度图像的宽度LONG lHeight = m_PhotoImage.GetHeight();  //获得灰度图像的高度size.cx = lWidth;size.cy = lHeight;CDC *pDC = GetDC();m_PhotoImage.Draw(pDC, point, size);//绘制处理前的图像//CSegmentDoc *pDoc = GetDocument();//CDib *pDib = pDoc->GetDib();if (m_PhotoImage.IsValid()){if (!m_PhotoImage.IsGrade()){AfxMessageBox("本程序只支持灰度位图!");return;}else{CEdgeDetection edgeDetection(&m_PhotoImage);edgeDetection.GuassLaplacian();//Invalidate();CPoint point1;point1.x = lWidth + 20;  //+20是为了让两个图像显示时有个间隙point1.y = 0;m_PhotoImage.Draw(pDC, point1, size);//绘制处理后的图像}}
}//最大方差阈值分割 响应事件函数
//此函数调用多次后,图像不会显示 这个是什么原因?!!
void C基于单文档的图像分割View::OnOtusthreshold()
{// TODO:  在此添加命令处理程序代码//最大方差阈值分割 响应事件函数if (flag == FALSE){AfxMessageBox("请先加载要处理的照片图像!");return;}CPoint point;CSize size;point.x = 0;point.y = 0;LONG lWidth = m_PhotoImage.GetWidth();    //获得灰度图像的宽度LONG lHeight = m_PhotoImage.GetHeight();  //获得灰度图像的高度size.cx = lWidth;size.cy = lHeight;CDC *pDC = GetDC();m_PhotoImage.Draw(pDC, point, size);//绘制处理前的图像//CSegmentDoc *pDoc = GetDocument();//CDib *pDib = pDoc->GetDib();if (m_PhotoImage.IsValid()){if (!m_PhotoImage.IsGrade()){AfxMessageBox("本程序只支持灰度位图!");return;}else{CThreshold threshold(&m_PhotoImage);threshold.OtusThreshold();//Invalidate();CPoint point1;point1.x = lWidth + 20;  //+20是为了让两个图像显示时有个间隙point1.y = 0;m_PhotoImage.Draw(pDC, point1, size);//绘制处理后的图像}}
}//自适应阈值分割 响应事件函数
void C基于单文档的图像分割View::OnAdapthresh()
{// TODO:  在此添加命令处理程序代码//如果之前没加载图像,将在这里提示if (flag == FALSE){AfxMessageBox("请先加载要处理的照片图像!");return;}CPoint point;CSize size;point.x = 0;point.y = 0;LONG lWidth = m_PhotoImage.GetWidth();    //获得灰度图像的宽度LONG lHeight = m_PhotoImage.GetHeight();  //获得灰度图像的高度size.cx = lWidth;size.cy = lHeight;CDC *pDC = GetDC();m_PhotoImage.Draw(pDC, point, size);//绘制处理前的图像//CSegmentDoc *pDoc = GetDocument();//CDib *pDib = pDoc->GetDib();if (m_PhotoImage.IsValid()){if (!m_PhotoImage.IsGrade()){AfxMessageBox("本程序只支持灰度位图!");return;}else{CThreshold threshold(&m_PhotoImage);threshold.AdaptiveThreshold();//Invalidate();CPoint point1;point1.x = lWidth + 20;  //+20是为了让两个图像显示时有个间隙point1.y = 0;m_PhotoImage.Draw(pDC, point1, size);//绘制处理后的图像}}
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词