// DibImage.h: interface for the CDibImage class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_DIBIMAGE_H__7DE2EE87_190A_4BFD_BBF3_CCC615C53419__INCLUDED_) #define AFX_DIBIMAGE_H__7DE2EE87_190A_4BFD_BBF3_CCC615C53419__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #define Pos(i,j) ((i)*Width + j) //#define PosBuf(i,j) (54+sizeof(RGBQUAD)*256 +i*Width + j) typedef struct { int Height; int Width; }Point; class CDibImage { public: CDibImage(); virtual ~CDibImage(); public: /* BYTE *pBuffer ——为图像的灰度数据区域; */ void Filter(BYTE *pBuffer, int MinValue, int MaxValue, int Height, int Width); //设置最大最小值 void FilterBuffer(BYTE *pBuffer, int MinValue, int MaxValue, int Height, int Width); //设置最大最小值 void RemoveBlack(BYTE *pBuffer, int nLianTong, int nSetValue, const int Height , const int Width); //消除杂质灰点 void MidFilter(BYTE *pBuffer, int nNumber, int Height, int Width); //中值滤波 void Averary(BYTE *pBuffer, int Height, int Width);//均值滤波 void Filter124(BYTE *pBuffer, int Height, int Width); //3*3的加权中值滤波;中间像素4倍,十字处像素2倍,四角像素1倍 void ChaoXianAverary(BYTE *pBuffer, int nTValue, int Height, int Width);//该点大于周围8点平均值,则平均值赋给该点,否则不变 void JuBuAverary(BYTE *pBuffer, int Height, int Width); //局部平均化 void VertialEdge(BYTE *pBuffer, int Height, int Width);//得到垂直边界Vertial void HorizontalEdge(BYTE *pBuffer, int Height, int Width);//得到水平边界horizontal void GetEdge(BYTE *pBuffer, int Height, int Width); // 得到图像边界 //锐化 void SharpenMenXian(BYTE *pBuffer, int nMenXianValue, int Height, int Width);//门限锐化 void SharpenGuDing(BYTE *pBuffer, int nMenXianValue, int Height, int Width);//特定灰度锐化 void SharpenErZhiHua(BYTE *pBuffer, int nMenXianValue, int Height, int Width);//二值化梯度锐化 //边缘检测 void EdgeRobert(BYTE *pBuffer, int Height, int Width);//Robert算子 void Edge_Temple(BYTE *pBuffer, int Height, int Width, int TempH, int TempW, int TempMX, int TempMY, float *fpArray, float fTempCoef);//算子的模板(卷积运算) void EdgeSobel(BYTE *pBuffer, int Height, int Width);//Sobel算子 void EdgePrewitt(BYTE *pBuffer, int Height, int Width);//Prewitt算子 void EdgeKrisch(BYTE *pBuffer, int Height, int Width);//Krisch算子 void EdgeGaussLaplacian(BYTE *pBuffer, int Height, int Width);//GaussLaplacian算子 //图像阈值分割 void FenGeZhiFangTu(BYTE *pBuffer, float *fTongji, int Height, int Width); //直方图统计 void FenGeYuZhi(BYTE *pBuffer, int nYuZhi, int Height, int Width); // 阈值分割 void FenGeBanYuZhi(BYTE *pBuffer, int nYuZhi, int Height, int Width); //半阈值分割 void FenGeDieDai(BYTE *pBuffer, int Height, int Width); //迭代阈值分割 //轮廓提取 void OutlineGet(BYTE *pBuffer, int Height, int Width);//轮廓提取 void OutlineTrack(BYTE *pBuffer, int Height, int Width);//轮廓跟踪 //图像的测量(面积、周长) void MeasureBiaoJi(BYTE *pBuffer, int Height, int Width); //对图像区域进行标记 }; #endif // !defined(AFX_DIBIMAGE_H__7DE2EE87_190A_4BFD_BBF3_CCC615C53419__INCLUDED_)
// DibImage.cpp: implementation of the CDibImage class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include <string.h> #include <math.h> #include "HVSnapPnp.h" #include "DibImage.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CDibImage::CDibImage() { } CDibImage::~CDibImage() { } //最大最小值 void CDibImage::Filter(BYTE *pBuffer, int MinValue, int MaxValue, int Height, int Width) { int i,j; for (i=0;i<Height;i++) { for (j=0; j<Width; j++) { if (pBuffer[Pos(i,j)] > MaxValue) { pBuffer[Pos(i,j)] = 255; } else if (pBuffer[Pos(i,j)] < MinValue) { pBuffer[Pos(i,j)] = 0; } } } } //最大最小值,加白区 void CDibImage::FilterBuffer(BYTE *pBuffer, int MinValue, int MaxValue, int Height, int Width) { int i,j; BYTE *pTemp= new BYTE[Height * Width]; memcpy(pTemp, pBuffer, Height*Width*sizeof(BYTE)); for (i=200;i<Height-512;i++) { for (j=500; j<Width-500; j++) { if (pTemp[Pos(i,j)] > MaxValue) { pTemp[Pos(i,j)] = 255; } // else if (pData[Pos(i,j)] < MinValue) // { // pTemp[Pos(i,j)] = 0; // } } } memcpy(pBuffer, pTemp, Height*Width*sizeof(BYTE)); // for (i=0;i<200;i++) // { // for (j=0; j<500; j++) // { // pBuffer[Pos(i,j)] = 255; // } // } delete []pTemp; } //均值滤波 void CDibImage::Averary(BYTE *pBuffer, int Height, int Width) { int i,j; int nAverary; BYTE *pTemp = new BYTE[Height * Width]; memcpy(pTemp, 0, Height*Width*sizeof(BYTE)); for (i=200;i<Height-512;i++) { for (j=500; j<Width-500; j++) { nAverary = 0; nAverary = (int)((pBuffer[Pos(i-1,j+1)] + pBuffer[Pos(i-1,j)]+ pBuffer[Pos(i-1,j-1)] + pBuffer[Pos(i,j+1)] + pBuffer[Pos(i,j-1)] + pBuffer[Pos(i+1,j-1)] + pBuffer[Pos(i+1,j)] + pBuffer[Pos(i+1,j+1)])/8); *(pTemp+i*Width+j) = nAverary; } } memcpy(pBuffer, pTemp, Height*Width*sizeof(BYTE)); delete []pTemp; } /* 功能:中值滤波 参数:int nNumber ——3:3*3中值滤波 ,5:5*5中值滤波 */ void CDibImage::MidFilter(BYTE *pBuffer, int nNumber, int Height, int Width) { int i,j; int m,n,g; int nEdge; //n*n忽略的边界;比如:3*3的忽略边界的1条像素 int nSort, nSortTemp; //排序变量 long size = Height * Width; int MidArray[100]; BYTE *pTemp = new BYTE[size]; memcpy(pTemp,0,size*sizeof(BYTE)); nEdge = (nNumber-1)/2; //MidFilter for (i=1;i<Height-1;i++) { for (j=1; j<Width-1; j++) { g=0; for (m=i-nEdge;m<i+nEdge;m++) { for (n=j-nEdge;n<j+nEdge;n++) { MidArray[g] = pBuffer[Pos(m,n)]; g++; } } do { nSort = 0; for (i=0;i<8-1;i++) { if (MidArray[i] > MidArray[i+1]) { nSortTemp = MidArray[i]; MidArray[i] = MidArray[i+1]; MidArray[i+1] = nSortTemp; nSort = 1; } } } while (nSort == 1); pTemp[Pos(i,j)] = MidArray[5]; } } //将处理后的pTemp赋给pBuffer memcpy(pBuffer, pTemp, Height*Width*sizeof(BYTE)); delete []pTemp; } /* 功能:消除杂质灰点 参数:nLianTong——4:连通,8连通 nSetValue——设定的周围的灰度平均值 */ void CDibImage::RemoveBlack(BYTE *pBuffer, int nLianTong, int nSetValue, const int Height , const int Width) { int i,j; int n4JunZhi, n8JunZhi; BYTE *pTemp = new BYTE[Height * Width]; memcpy(pTemp, 0, Height*Width*sizeof(BYTE)); if (nLianTong == 4) { for (i=1;i<Height-1;i++) { for (j=1;j<Width-1;j++) { n4JunZhi = 0; n4JunZhi = (pBuffer[Pos(i,j+1)] + pBuffer[Pos(i-1,j)] + pBuffer[Pos(i+1,j)] + pBuffer[Pos(i,j-1)]) / 4; if (n4JunZhi > nSetValue) pTemp[Pos(i,j)] = 255; } } } else if (nLianTong == 8) { for (i=1;i<Height-1;i++) { for (j=1;j<Width-1;j++) { n8JunZhi = 0; n8JunZhi = (pBuffer[Pos(i-1,j+1)]+pBuffer[Pos(i,j+1)]+pBuffer[Pos(i+1,j+1)] +pBuffer[Pos(i-1,j)] +pBuffer[Pos(i+1,j)] +pBuffer[Pos(i-1,j-1)]+pBuffer[Pos(i,j-1)]+pBuffer[Pos(i+1,j-1)])/8; if (n8JunZhi > nSetValue) pTemp[Pos(i,j)] = 255; } } } else AfxMessageBox("请将参数设为:4 或者 8 !"); delete []pTemp; } /* //3*3的加权中值滤波;(中间像素4倍,十字处像素2倍,四角像素1倍) / 16; 函数说明: 1 2 1 2 4 2 1 2 1 */ void CDibImage::Filter124(BYTE *pBuffer, int Height, int Width) { int i,j; int nAverary; BYTE *pTemp = new BYTE[Height * Width]; memcpy(pTemp, 0, Height*Width*sizeof(BYTE)); for (i=1;i<Height-1;i++) { for (j=1; j<Width-1; j++) { nAverary = 0; nAverary = (int)((pBuffer[Pos(i-1,j+1)]*1 + pBuffer[Pos(i-1,j)]*2+ pBuffer[Pos(i-1,j-1)]*1 + pBuffer[Pos(i,j+1)]*2 + pBuffer[Pos(i,j-1)]*2 + pBuffer[Pos(i+1,j-1)]*1 + pBuffer[Pos(i+1,j)]*2 + pBuffer[Pos(i+1,j+1)]*1 + pBuffer[Pos(i,j)]*4) /16); *(pTemp+i*Width+j) = nAverary; } } memcpy(pBuffer, pTemp, Height*Width*sizeof(BYTE)); delete []pTemp; } /* 函数:ChaoXianAverary()——超限邻域平均法 功能说明:选取周围8点像素值,如果该点大于平均值,则平均值赋给该点,否则不变 参数:BYTE *pBuffer —— 图像数据区 int nTValue —— 设定阈值 (判断该点值与平均值) abs(*(pTemp+i*Width+j) - nAverary) > nTValue */ void CDibImage::ChaoXianAverary(BYTE *pBuffer, int nTValue, int Height, int Width) { int i,j; int nAverary; BYTE *pTemp = new BYTE[Height * Width]; memcpy(pTemp, 0, Height*Width*sizeof(BYTE)); for (i=1;i<Height-1;i++) { for (j=1; j<Width-1; j++) { nAverary = 0; nAverary = (int)((pBuffer[Pos(i-1,j+1)] + pBuffer[Pos(i-1,j)]+ pBuffer[Pos(i-1,j-1)] + pBuffer[Pos(i,j+1)] + pBuffer[Pos(i,j-1)] + pBuffer[Pos(i+1,j-1)] + pBuffer[Pos(i+1,j)] + pBuffer[Pos(i+1,j+1)]) / 8); if (abs(*(pTemp+i*Width+j) - nAverary) > nTValue) { *(pTemp+i*Width+j) = nAverary; } } } memcpy(pBuffer, pTemp, Height*Width*sizeof(BYTE)); delete []pTemp; } /************************************************************************/ /* 函数:局部平均化 说明:取5*5窗口;选取4个五边形,4个六边形,一个边长为3的正方形 得到它们的平均值跟方差;采用方差最小的进行平均化。 也称为:自适应平滑方法。 */ /************************************************************************/ void CDibImage::JuBuAverary(BYTE *pBuffer, int Height, int Width) //局部平均化 { int i,j,k; //循环变量 float JunZhi[9] = {0,0,0,0,0,0,0,0,0}; //某区域均值 float FangCha[9] = {0,0,0,0,0,0,0,0,0};//某区域方差 int nData[9] = {0,0,0,0,0,0,0,0,0}; //某区域数据 int Sum = 0; //某区域数据之和 int nNum = 0; //最终选择的区域 float FangChaMin = 0.0; //最小方差 BYTE *pTemp = new BYTE[Height * Width]; //中间缓冲区 memcpy(pTemp, 0, Height*Width*sizeof(BYTE)); for (i=2;i<Height-2;i++) { for (j=2;j<Width-2;j++) { //九块区域 //第一块区域——中间的边长为3的正方形 nData[0] = pBuffer[Pos(i-1,j+1)]; nData[1] = pBuffer[Pos(i ,j+1)]; nData[2] = pBuffer[Pos(i+1,j+1)]; nData[3] = pBuffer[Pos(i-1,j )]; nData[4] = pBuffer[Pos(i ,j )]; nData[5] = pBuffer[Pos(i+1,j )]; nData[6] = pBuffer[Pos(i-1,j-1)]; nData[7] = pBuffer[Pos(i ,j-1)]; nData[8] = pBuffer[Pos(i+1,j-1)]; for (k=0;k<9;k++) Sum += nData[k]; JunZhi[0] = (float)(Sum/9); //均值 for (k=0;k<9;k++) FangCha[0] += nData[k]*nData[k] - JunZhi[0]*JunZhi[0]; //方差 //第二块区域——上五边形 nData[0] = pBuffer[Pos(i-1,j+2)]; nData[1] = pBuffer[Pos(i ,j+2)]; nData[2] = pBuffer[Pos(i+1,j+2)]; nData[3] = pBuffer[Pos(i-1,j+1)]; nData[4] = pBuffer[Pos(i ,j )]; nData[5] = pBuffer[Pos(i+1,j+1)]; nData[6] = pBuffer[Pos(i-1,j+1)]; for (k=0;k<7;k++) Sum += nData[k]; JunZhi[1] = (float)(Sum/7); for (k=0;k<7;k++) FangCha[1] += nData[k]*nData[k] - JunZhi[1]*JunZhi[1]; //第三块区域——下五边形 nData[0] = pBuffer[Pos(i-1,j-2)]; nData[1] = pBuffer[Pos(i ,j-2)]; nData[2] = pBuffer[Pos(i+1,j-2)]; nData[3] = pBuffer[Pos(i-1,j-1)]; nData[4] = pBuffer[Pos(i ,j )]; nData[5] = pBuffer[Pos(i+1,j-1)]; nData[6] = pBuffer[Pos(i-1,j-1)]; for (k=0;k<7;k++) Sum += nData[k]; JunZhi[2] = (float)(Sum/7); for (k=0;k<7;k++) FangCha[2] += nData[k]*nData[k] - JunZhi[2]*JunZhi[2]; //第四块区域——左五边形 nData[0] = pBuffer[Pos(i-2,j )]; nData[1] = pBuffer[Pos(i-1,j-1)]; nData[2] = pBuffer[Pos(i-1,j )]; nData[3] = pBuffer[Pos(i-2,j-1)]; nData[4] = pBuffer[Pos(i ,j )]; nData[5] = pBuffer[Pos(i-1,j+1)]; nData[6] = pBuffer[Pos(i-2,j+1)]; for (k=0;k<7;k++) Sum += nData[k]; JunZhi[3] = (float)(Sum/7); for (k=0;k<7;k++) FangCha[3] += nData[k]*nData[k] - JunZhi[3]*JunZhi[3]; //第五块区域——右五边形 nData[0] = pBuffer[Pos(i+2,j )]; nData[1] = pBuffer[Pos(i+1,j-1)]; nData[2] = pBuffer[Pos(i+1,j )]; nData[3] = pBuffer[Pos(i+2,j-1)]; nData[4] = pBuffer[Pos(i ,j )]; nData[5] = pBuffer[Pos(i+1,j+1)]; nData[6] = pBuffer[Pos(i+2,j+1)]; for (k=0;k<7;k++) Sum += nData[k]; JunZhi[4] = (float)(Sum/7); for (k=0;k<7;k++) FangCha[4] += nData[k]*nData[k] - JunZhi[4]*JunZhi[4]; //第六块区域——左上六边形 nData[0] = pBuffer[Pos(i ,j )]; nData[1] = pBuffer[Pos(i-1,j )]; nData[2] = pBuffer[Pos(i ,j+1)]; nData[3] = pBuffer[Pos(i-2,j+2)]; nData[4] = pBuffer[Pos(i-1,j+2)]; nData[5] = pBuffer[Pos(i-1,j+1)]; nData[6] = pBuffer[Pos(i-2,j+1)]; for (k=0;k<7;k++) Sum += nData[k]; JunZhi[5] = (float)(Sum/7); for (k=0;k<7;k++) FangCha[5] += nData[k]*nData[k] - JunZhi[5]*JunZhi[5]; //第七块区域——右上六边形 nData[0] = pBuffer[Pos(i ,j )]; nData[1] = pBuffer[Pos(i+1,j )]; nData[2] = pBuffer[Pos(i ,j+1)]; nData[3] = pBuffer[Pos(i+2,j+2)]; nData[4] = pBuffer[Pos(i+1,j+2)]; nData[5] = pBuffer[Pos(i+1,j+1)]; nData[6] = pBuffer[Pos(i+2,j+1)]; for (k=0;k<7;k++) Sum += nData[k]; JunZhi[6] = (float)(Sum/7); for (k=0;k<7;k++) FangCha[6] += nData[k]*nData[k] - JunZhi[6]*JunZhi[6]; //第八块区域——左下六边形 nData[0] = pBuffer[Pos(i ,j )]; nData[1] = pBuffer[Pos(i-1,j )]; nData[2] = pBuffer[Pos(i ,j-1)]; nData[3] = pBuffer[Pos(i-2,j-2)]; nData[4] = pBuffer[Pos(i-1,j-2)]; nData[5] = pBuffer[Pos(i-1,j-1)]; nData[6] = pBuffer[Pos(i-2,j-1)]; for (k=0;k<7;k++) Sum += nData[k]; JunZhi[7] = (float)(Sum/7); for (k=0;k<7;k++) FangCha[7] += nData[k]*nData[k] - JunZhi[7]*JunZhi[7]; //第九块区域——右下六边形 nData[0] = pBuffer[Pos(i ,j )]; nData[1] = pBuffer[Pos(i+1,j )]; nData[2] = pBuffer[Pos(i ,j-1)]; nData[3] = pBuffer[Pos(i+2,j-2)]; nData[4] = pBuffer[Pos(i+1,j-2)]; nData[5] = pBuffer[Pos(i+1,j-1)]; nData[6] = pBuffer[Pos(i+2,j-1)]; for (k=0;k<7;k++) Sum += nData[k]; JunZhi[8] = (float)(Sum/7); for (k=0;k<7;k++) FangCha[8] += nData[k]*nData[k] - JunZhi[8]*JunZhi[8]; //得到方差最小的那块K区域 FangChaMin = FangCha[0]; for (k=0;k<9;k++) { if (FangChaMin > FangCha[k]) { FangChaMin = FangCha[k]; nNum = k; } } pTemp[Pos(i,j)] = (int)(JunZhi[k] + 0.5); } } memcpy(pBuffer, pTemp, Height*Width*sizeof(BYTE)); delete []pTemp; } //得到垂直边界Vertial void CDibImage::VertialEdge(BYTE *pBuffer, int Height, int Width) { int i,j; BYTE *pTemp = new BYTE[Height * Width]; memcpy(pTemp, 0, Height*Width*sizeof(BYTE)); for (i=1;i<Height-1;i++) { for (j=1; j<Width-1; j++) { pTemp[Pos(i,j)] = abs(pBuffer[Pos(i,j)] - pBuffer[Pos(i,j-1)]); } } memcpy(pBuffer, pTemp, Height*Width*sizeof(BYTE)); delete []pTemp; } //得到水平边界horizontal void CDibImage::HorizontalEdge(BYTE *pBuffer, int Height, int Width) { int i,j; BYTE *pTemp = new BYTE[Height * Width]; memcpy(pTemp, 0, Height*Width*sizeof(BYTE)); for (i=1;i<Height-1;i++) { for (j=1; j<Width-1; j++) { pTemp[Pos(i,j)] = abs(pBuffer[Pos(i,j)] - pBuffer[Pos(i-1,j)]); } } memcpy(pBuffer, pTemp, Height*Width*sizeof(BYTE)); delete []pTemp; } // 得到图像边界 void CDibImage::GetEdge(BYTE *pBuffer, int Height, int Width) { int i,j; BYTE *pTemp = new BYTE[Height * Width]; memcpy(pTemp, 0, Height * Width * sizeof(BYTE)); for (i=1;i<Height;i++) { for (j=1;j<Width;j++) { pTemp[Pos(i,j)] = (int)sqrt((pBuffer[Pos(i,j)] - pBuffer[Pos(i,j-1)])*(pBuffer[Pos(i,j)] - pBuffer[Pos(i,j-1)]) + (pBuffer[Pos(i,j)] - pBuffer[Pos(i-1,j)])*(pBuffer[Pos(i,j)] - pBuffer[Pos(i-1,j)])); } } memcpy(pBuffer, pTemp, Height*Width*sizeof(BYTE)); delete []pTemp; } /************************************************************************/ /* 函数:SharpenMenXian()——门限梯度锐化 参数:int nMenXianValue——门限值(参考取值:30) 说明:if( G(i,j) > T) G(i,j) = G(f(i,j)) + 100; else G(i,j) = f(i,j); 公式:G(f(i,j)) = sqrt((f(i,j)-f(i,j-1))*(f(i,j)-f(i,j-1)) + (f(i,j)-f(i-1,j))*(f(i,j)-f(i-1,j))) */ /************************************************************************/ void CDibImage::SharpenMenXian(BYTE *pBuffer, int nMenXianValue, int Height, int Width) { int i,j; int nTemp = 0; BYTE *pTemp = new BYTE[Height * Width]; memcpy(pTemp, 0, Height * Width * sizeof(BYTE)); for (i=1;i<Height;i++) { for (j=1;j<Width;j++) { nTemp = (int)sqrt((pBuffer[Pos(i,j)] - pBuffer[Pos(i,j-1)])*(pBuffer[Pos(i,j)] - pBuffer[Pos(i,j-1)]) + (pBuffer[Pos(i,j)] - pBuffer[Pos(i-1,j)])*(pBuffer[Pos(i,j)] - pBuffer[Pos(i-1,j)])); if (nTemp > nMenXianValue) //如果大于门限值(30) { if (nTemp + 100 > 255) pTemp[Pos(i,j)] = 255; else pTemp[Pos(i,j)] = nTemp + 100; } if (nTemp < 30) //如果小于门限值,则将原数据赋给pTemp pTemp[Pos(i,j)] = pBuffer[Pos(i,j)]; } } memcpy(pBuffer, pTemp, Height*Width*sizeof(BYTE)); delete []pTemp; } /************************************************************************/ /* 函数: 给边缘规定灰度(边缘为255) 与SharpenMenXian()差不多;只是超过门限值的直接赋255; 参数:int nMenXianValue——门限值(参考取值:30) 说明:if( G(i,j) > T) G(i,j) = 255; else G(i,j) = f(i,j); 公式:G(f(i,j)) = sqrt((f(i,j)-f(i,j-1))*(f(i,j)-f(i,j-1)) + (f(i,j)-f(i-1,j))*(f(i,j)-f(i-1,j))) */ /************************************************************************/ void CDibImage::SharpenGuDing(BYTE *pBuffer, int nMenXianValue, int Height, int Width) { int i,j; int nTemp = 0; BYTE *pTemp = new BYTE[Height * Width]; memcpy(pTemp, 0, Height * Width * sizeof(BYTE)); for (i=1;i<Height;i++) { for (j=1;j<Width;j++) { nTemp = (int)sqrt((pBuffer[Pos(i,j)] - pBuffer[Pos(i,j-1)])*(pBuffer[Pos(i,j)] - pBuffer[Pos(i,j-1)]) + (pBuffer[Pos(i,j)] - pBuffer[Pos(i-1,j)])*(pBuffer[Pos(i,j)] - pBuffer[Pos(i-1,j)])); if (nTemp > nMenXianValue) //如果大于门限值 pTemp[Pos(i,j)] = 255; else pTemp[Pos(i,j)] = pBuffer[Pos(i,j)]; } } memcpy(pBuffer, pTemp, Height*Width*sizeof(BYTE)); delete []pTemp; } /************************************************************************/ /* 函数: 给边缘规定灰度(边缘为255),其他区域为0; 与SharpenMenXian()差不多;只是超过门限值的直接赋255,其他区域为0; 参数:int nMenXianValue——门限值(参考取值:30) 说明:if( G(i,j) > T) G(i,j) = 255; else G(i,j) = 0; 公式:G(f(i,j)) = sqrt((f(i,j)-f(i,j-1))*(f(i,j)-f(i,j-1)) + (f(i,j)-f(i-1,j))*(f(i,j)-f(i-1,j))) */ /************************************************************************/ void CDibImage::SharpenErZhiHua(BYTE *pBuffer, int nMenXianValue, int Height, int Width) { int i,j; int nTemp = 0; BYTE *pTemp = new BYTE[Height * Width]; memcpy(pTemp, 0, Height * Width * sizeof(BYTE)); for (i=1;i<Height;i++) { for (j=1;j<Width;j++) { nTemp = (int)sqrt((pBuffer[Pos(i,j)] - pBuffer[Pos(i,j-1)])*(pBuffer[Pos(i,j)] - pBuffer[Pos(i,j-1)]) + (pBuffer[Pos(i,j)] - pBuffer[Pos(i-1,j)])*(pBuffer[Pos(i,j)] - pBuffer[Pos(i-1,j)])); if (nTemp > nMenXianValue) //如果大于门限值 pTemp[Pos(i,j)] = 255; else pTemp[Pos(i,j)] = 0; } } memcpy(pBuffer, pTemp, Height*Width*sizeof(BYTE)); delete []pTemp; } /************************************************************************/ /* 函数:边缘检测——Robert算子 公式:G(i,j) = sqrt((f(i,j)-f(i+1,j+1))*((f(i,j)-f(i+1,j+1))+(f(i+1,j)-f(i,j+1))*(f(i+1,j)-f(i,j+1))) 说明: (i,j+1) (i+1,j+1) (i,j ) (i+1,j ) */ /************************************************************************/ void CDibImage::EdgeRobert(BYTE *pBuffer, int Height, int Width) { int i,j; BYTE *pTemp = new BYTE[Height * Width]; memcpy(pTemp, 0, Height * Width * sizeof(BYTE)); int nRobert[4] = {0,0,0,0}; for (i=0;i<Height-1;i++) { for (j=0;j<Width-1;j++) { nRobert[0] = pBuffer[Pos(i,j)]; nRobert[1] = pBuffer[Pos(i,j+1)]; nRobert[2] = pBuffer[Pos(i+1,j)]; nRobert[3] = pBuffer[Pos(i+1,j+1)]; pTemp[Pos(i,j)] = (int)sqrt((nRobert[0]-nRobert[3])*(nRobert[0]-nRobert[3])+(nRobert[2]-nRobert[1])*(nRobert[2]-nRobert[1])); } } memcpy(pBuffer, pTemp, Height*Width*sizeof(BYTE)); delete []pTemp; } /************************************************************************/ /* 函数:算子模板处理(原图3*3与模板3*3进行卷积运算) 参数: int TempH——模板高 int TempW——模板宽 int TempMX——模板中心X int TempMY——模板中心Y float *fpArray——模板数组指针 float fTempCoef——模板系数 */ /************************************************************************/ void CDibImage::Edge_Temple(BYTE *pBuffer, int Height, int Width, int TempH, int TempW, int TempMX, int TempMY, float *fpArray, float fTempCoef) { int i,j,k,l; BYTE *pTemp = new BYTE[Height * Width]; memcpy(pTemp, 0, Height * Width * sizeof(BYTE)); float fResoult; for (i=TempMY;i<Height-TempH+TempMY+1;i++) { for (j=TempMX;j<Width-TempW+TempMX+1;j++) { fResoult = 0; for (k=0;k<TempH;k++) { for (l=0;l<TempW;l++) { fResoult += pBuffer[Pos((i-TempMY+k), (j-TempMX+1))]*fpArray[k*TempW+l]; fResoult *= fTempCoef; fResoult = (float)fabs(fResoult); if (fResoult>255) pTemp[Pos(i,j)] = 255; else pTemp[Pos(i,j)] = (int)(fResoult+0.5); } } } } memcpy(pBuffer, pTemp, Height*Width*sizeof(BYTE)); delete []pTemp; } /************************************************************************/ /* 函数:边缘检测——Sobel算子(索伯尔算子) 说明:调用两个模板进行卷积运算,取较大值;(进行水平、垂直边缘检测) 具有噪声抑制能力,边缘宽度至少为两个像素; 用来提取图像边缘; 模板1: -1 -2 -1 模板2: +1 0 -1 0 0 0 +2 0 -2 +1 +2 +1 +1 0 -1 */ /************************************************************************/ void CDibImage::EdgeSobel(BYTE *pBuffer, int Height, int Width) { int i,j; int TempH = 3; int TempW = 3; int TempMX = 1; int TempMY = 1; float fTempCoef = 1; float Template[9]; BYTE *pTemp1 = new BYTE[Height * Width]; memcpy(pTemp1, pBuffer, Height * Width * sizeof(BYTE)); BYTE *pTemp2 = new BYTE[Height * Width]; memcpy(pTemp2, pBuffer, Height * Width * sizeof(BYTE)); Template[0] = -1.0; Template[1] = -2.0; Template[2] = -1.0; Template[3] = 0; Template[4] = 0; Template[5] = 0; Template[6] = 1.0; Template[7] = 2.0; Template[8] = 1.0; Edge_Temple(pTemp1,Height,Width,TempH,TempW,TempMX,TempMY,Template,fTempCoef); Template[0] = -1.0; Template[1] = 0; Template[2] = 1.0; Template[3] = -2.0; Template[4] = 0; Template[5] = 2.0; Template[6] = -1.0; Template[7] = 0; Template[8] = 1.0; Edge_Temple(pTemp2,Height,Width,TempH,TempW,TempMX,TempMY,Template,fTempCoef); for (i=0;i<Height;i++) { for (j=0;j<Width;j++) { if (pTemp2[Pos(i,j)] > pTemp1[Pos(i,j)]) pTemp1[Pos(i,j)] = pTemp2[Pos(i,j)]; } } memcpy(pBuffer, pTemp1, Height*Width*sizeof(BYTE)); delete []pTemp1; delete []pTemp2; } /************************************************************************/ /* 函数:边缘检测——Prewitt算子(普瑞维特算子) 说明:调用两个模板进行卷积运算,取较大值;(进行水平、垂直边缘检测) 具有噪声抑制能力,边缘宽度至少为两个像素; 用来提取图像边缘; 模板1: -1 -1 -1 模板2: +1 0 -1 0 0 0 +1 0 -1 +1 +1 +1 +1 0 -1 */ /************************************************************************/ void CDibImage::EdgePrewitt(BYTE *pBuffer, int Height, int Width) { int i,j; int TempH = 3; int TempW = 3; int TempMX = 1; int TempMY = 1; float fTempCoef = 1; float Template[9]; BYTE *pTemp1 = new BYTE[Height * Width]; memcpy(pTemp1, pBuffer, Height * Width * sizeof(BYTE)); BYTE *pTemp2 = new BYTE[Height * Width]; memcpy(pTemp2, pBuffer, Height * Width * sizeof(BYTE)); Template[0] = -1.0; Template[1] = -1.0; Template[2] = -1.0; Template[3] = 0; Template[4] = 0; Template[5] = 0; Template[6] = 1.0; Template[7] = 1.0; Template[8] = 1.0; Edge_Temple(pTemp1,Height,Width,TempH,TempW,TempMX,TempMY,Template,fTempCoef); Template[0] = 1.0; Template[1] = 0; Template[2] = -1.0; Template[3] = 1.0; Template[4] = 0; Template[5] = -1.0; Template[6] = 1.0; Template[7] = 0; Template[8] = -1.0; Edge_Temple(pTemp2,Height,Width,TempH,TempW,TempMX,TempMY,Template,fTempCoef); for (i=0;i<Height;i++) { for (j=0;j<Width;j++) { if (pTemp2[Pos(i,j)] > pTemp1[Pos(i,j)]) pTemp1[Pos(i,j)] = pTemp2[Pos(i,j)]; } } memcpy(pBuffer, pTemp1, Height*Width*sizeof(BYTE)); delete []pTemp1; delete []pTemp2; } /************************************************************************/ /* 函数:边缘检测——Krisch算子(克瑞斯算子) 说明:调用模板进行卷积运算,取较大值; Krisch算子有8个方向; */ /************************************************************************/ void CDibImage::EdgeKrisch(BYTE *pBuffer, int Height, int Width) { int i,j; int TempH = 3; int TempW = 3; int TempMX = 1; int TempMY = 1; float fTempCoef = 0.5; float Template[9]; BYTE *pTemp1 = new BYTE[Height * Width]; memcpy(pTemp1, pBuffer, Height * Width * sizeof(BYTE)); BYTE *pTemp2 = new BYTE[Height * Width]; memcpy(pTemp2, pBuffer, Height * Width * sizeof(BYTE)); //模板1参数 Template[0] = 5.0; Template[1] = 5.0; Template[2] = 5.0; Template[3] = -3.0; Template[4] = 0; Template[5] = -3.0; Template[6] = -3.0; Template[7] = -3.0; Template[8] = -3.0; Edge_Temple(pTemp1,Height,Width,TempH,TempW,TempMX,TempMY,Template,fTempCoef); //模板2参数 Template[0] = -3.0; Template[1] = 5.0; Template[2] = 5.0; Template[3] = -3.0; Template[4] = 0; Template[5] = 5.0; Template[6] = -3.0; Template[7] = -3.0; Template[8] = -3.0; Edge_Temple(pTemp2,Height,Width,TempH,TempW,TempMX,TempMY,Template,fTempCoef); for (i=0;i<Height;i++) { for (j=0;j<Width;j++) { if (pTemp2[Pos(i,j)] > pTemp1[Pos(i,j)]) pTemp1[Pos(i,j)] = pTemp2[Pos(i,j)]; } } memcpy(pTemp2,pBuffer,Height*Width*sizeof(BYTE)); //模板3参数 Template[0] = -3.0; Template[1] = -3.0; Template[2] = 5.0; Template[3] = -3.0; Template[4] = 0; Template[5] = 5.0; Template[6] = -3.0; Template[7] = -3.0; Template[8] = 5.0; Edge_Temple(pTemp2,Height,Width,TempH,TempW,TempMX,TempMY,Template,fTempCoef); for (i=0;i<Height;i++) { for (j=0;j<Width;j++) { if (pTemp2[Pos(i,j)] > pTemp1[Pos(i,j)]) pTemp1[Pos(i,j)] = pTemp2[Pos(i,j)]; } } memcpy(pTemp2,pBuffer,Height*Width*sizeof(BYTE)); //模板4参数 Template[0] = -3.0; Template[1] = -3.0; Template[2] = -3.0; Template[3] = -3.0; Template[4] = 0; Template[5] = 5.0; Template[6] = -3.0; Template[7] = 5.0; Template[8] = 5.0; Edge_Temple(pTemp2,Height,Width,TempH,TempW,TempMX,TempMY,Template,fTempCoef); for (i=0;i<Height;i++) { for (j=0;j<Width;j++) { if (pTemp2[Pos(i,j)] > pTemp1[Pos(i,j)]) pTemp1[Pos(i,j)] = pTemp2[Pos(i,j)]; } } memcpy(pTemp2,pBuffer,Height*Width*sizeof(BYTE)); //模板5参数 Template[0] = -3.0; Template[1] = -3.0; Template[2] = -3.0; Template[3] = -3.0; Template[4] = 0; Template[5] = -3.0; Template[6] = 5.0; Template[7] = 5.0; Template[8] = 5.0; Edge_Temple(pTemp2,Height,Width,TempH,TempW,TempMX,TempMY,Template,fTempCoef); for (i=0;i<Height;i++) { for (j=0;j<Width;j++) { if (pTemp2[Pos(i,j)] > pTemp1[Pos(i,j)]) pTemp1[Pos(i,j)] = pTemp2[Pos(i,j)]; } } memcpy(pTemp2,pBuffer,Height*Width*sizeof(BYTE)); //模板6参数 Template[0] = -3.0; Template[1] = -3.0; Template[2] = -3.0; Template[3] = 5.0; Template[4] = 0; Template[5] = -3.0; Template[6] = 5.0; Template[7] = 5.0; Template[8] = -3.0; Edge_Temple(pTemp2,Height,Width,TempH,TempW,TempMX,TempMY,Template,fTempCoef); for (i=0;i<Height;i++) { for (j=0;j<Width;j++) { if (pTemp2[Pos(i,j)] > pTemp1[Pos(i,j)]) pTemp1[Pos(i,j)] = pTemp2[Pos(i,j)]; } } memcpy(pTemp2,pBuffer,Height*Width*sizeof(BYTE)); //模板7参数 Template[0] = 5.0; Template[1] = -3.0; Template[2] = -3.0; Template[3] = 5.0; Template[4] = 0; Template[5] = -3.0; Template[6] = 5.0; Template[7] = -3.0; Template[8] = -3.0; Edge_Temple(pTemp2,Height,Width,TempH,TempW,TempMX,TempMY,Template,fTempCoef); for (i=0;i<Height;i++) { for (j=0;j<Width;j++) { if (pTemp2[Pos(i,j)] > pTemp1[Pos(i,j)]) pTemp1[Pos(i,j)] = pTemp2[Pos(i,j)]; } } memcpy(pTemp2,pBuffer,Height*Width*sizeof(BYTE)); //模板8参数 Template[0] = 5.0; Template[1] = 5.0; Template[2] = -3.0; Template[3] = 5.0; Template[4] = 0; Template[5] = -3.0; Template[6] = -3.0; Template[7] = -3.0; Template[8] = -3.0; Edge_Temple(pTemp2,Height,Width,TempH,TempW,TempMX,TempMY,Template,fTempCoef); for (i=0;i<Height;i++) { for (j=0;j<Width;j++) { if (pTemp2[Pos(i,j)] > pTemp1[Pos(i,j)]) pTemp1[Pos(i,j)] = pTemp2[Pos(i,j)]; } } ////////////////////////////////////////////////////////////////////////// memcpy(pBuffer, pTemp1, Height*Width*sizeof(BYTE)); delete []pTemp1; delete []pTemp2; } /************************************************************************/ /* 函数:边缘检测——GaussLaplacian算子(高斯拉普拉斯算子) 说明:Laplacian算子是线形二阶微分算子,具有旋转不变性; 高斯平滑滤波器与Laplacian锐化滤波器结合;先平滑滤波,再边缘检测; */ /************************************************************************/ void CDibImage::EdgeGaussLaplacian(BYTE *pBuffer, int Height, int Width) { int TempH = 5; int TempW = 5; int TempMX = 4; int TempMY = 4; float fTempCoef = 0.25; float Template[25]; BYTE *pTemp1 = new BYTE[Height * Width]; memcpy(pTemp1, pBuffer, Height * Width * sizeof(BYTE)); //设置GuassLaplacian模板参数 Template[0]=-2.0; Template[1]=-4.0; Template[2]=-4.0; Template[3]=-4.0; Template[4]=-2.0; Template[5]=-4.0; Template[6]=0.0; Template[7]=8.0; Template[8]=0.0; Template[9]=-4.0; Template[10]=-4.0; Template[11]=8.0; Template[12]=24.0; Template[13]=8.0; Template[14]=-4.0; Template[15]=-4.0; Template[16]=0.0; Template[17]=8.0; Template[18]=0.0; Template[19]=-4.0; Template[20]=-2.0; Template[21]=-4.0; Template[22]=-4.0; Template[23]=-4.0; Template[24]=-2.0; Edge_Temple(pTemp1,Height,Width,TempH,TempW,TempMX,TempMY,Template,fTempCoef); memcpy(pBuffer, pTemp1, Height*Width*sizeof(BYTE)); delete []pTemp1; } /************************************************************************/ /* 函数:图像分割——阈值分割 说明:灰度值与阈值之差的绝对值小于30,则将阈值赋给图像点; */ /************************************************************************/ void CDibImage::FenGeYuZhi(BYTE *pBuffer, int nYuZhi, int Height, int Width) { int i,j; BYTE *pTemp = new BYTE[Height * Width]; memcpy(pTemp, 0, Height*Width*sizeof(BYTE)); for (i=0;i<Height;i++) { for (j=0; j<Width; j++) { if (abs(pBuffer[Pos(i,j)] - nYuZhi) < 30) { pTemp[Pos(i,j)] = nYuZhi; } } } memcpy(pBuffer, pTemp, Height*Width*sizeof(BYTE)); delete []pTemp; } /************************************************************************/ /* 函数:图像分割——半阈值分割 说明:保留阈值以外的图像部分,半阈值分割消除的是图像背景; */ /************************************************************************/ void CDibImage::FenGeBanYuZhi(BYTE *pBuffer, int nYuZhi, int Height, int Width) { int i,j; BYTE *pTemp = new BYTE[Height * Width]; memcpy(pTemp, 0, Height*Width*sizeof(BYTE)); for (i=0;i<Height;i++) { for (j=0; j<Width; j++) { if (abs(pBuffer[Pos(i,j)] - nYuZhi) < 30) { pTemp[Pos(i,j)] = pBuffer[Pos(i,j)]; } } } memcpy(pBuffer, pTemp, Height*Width*sizeof(BYTE)); delete []pTemp; } //直方图统计 void CDibImage::FenGeZhiFangTu(BYTE *pBuffer, float *fTongji, int Height, int Width) { int i,j; int huidu[256]; memset(huidu, 0, sizeof(huidu)); BYTE *pTemp = new BYTE[Height * Width]; memcpy(pTemp, pBuffer, Height*Width*sizeof(BYTE)); for (i=0;i<Height;i++) { for (j=0; j<Width; j++) { unsigned char Temp = pTemp[Pos(i,j)]; huidu[Temp]++; } } for (i=0;i<256;i++) fTongji[i] = huidu[i]/(Height*Width*1.0f); } /************************************************************************/ /* 函数:图像分割——迭代阈值分割 说明:应该选择图像的平均灰度来作为初始的阈值(T1); 以此阈值作为间隔,分成两组1与2,计算两组的平均灰度T = (u1+u2)/2; 以T为新阈值,重复上述操作;直到u1与u2不变; */ /************************************************************************/ void CDibImage::FenGeDieDai(BYTE *pBuffer, int Height, int Width) //迭代阈值分割 { float *fTongji = new float[256]; memset(fTongji,0,sizeof(fTongji)); int i,j; int T1,T2; //迭代阈值 T1 = 127; T2 = 0; float temp1,temp2,temp3,temp4; temp1 = temp2 = temp3 = temp4 = 0; FenGeZhiFangTu(pBuffer,fTongji,Height,Width); while(true) { for (i=0;i<T1;i++) { temp1 += fTongji[i] * i; temp2 += fTongji[i]; } for (j=T1;j<256;j++) { temp3 += fTongji[j] * j; temp4 += fTongji[j]; } T2 = (int)((temp1/temp2 + temp3/temp4)/2); if (T1 == T2) break; else T1 = T2; } for (i=0;i<Height;i++) { for (j=0; j<Width; j++) { unsigned char Temp = pBuffer[Pos(i,j)]; if (Temp < T1) Temp = 0; ////////////////////////保留部分(目标图像区)——白色 ??? else Temp = 255; /////////////////////////背景色 pBuffer[Pos(i,j)] = Temp; } } } /************************************************************************/ /* 函数:轮廓提取; 说明:只是显示出图像上的目标物的轮廓; */ /************************************************************************/ void CDibImage::OutlineGet(BYTE *pBuffer, int Height, int Width) { int i,j; int a1,a2,a3,a4,a5,a6,a7,a8; //先二值化 for (i=0;i<Height;i++) { for (j=0;j<Width;j++) { if (pBuffer[Pos(i,j)] > 200) pBuffer[Pos(i,j)] = 255; else pBuffer[Pos(i,j)] = 0; } } BYTE *pTemp = new BYTE[Height * Width]; memcpy(pTemp, 0, Height*Width*sizeof(BYTE)); for (i=1;i<Height-1;i++) { for (j=1;j<Width-1;j++) { if (pBuffer[Pos(i,j)] == 255) { pTemp[Pos(i,j)] = 255; a1 = pBuffer[Pos(i+1,j-1)]; a2 = pBuffer[Pos(i+1,j )]; a3 = pBuffer[Pos(i+1,j+1)]; a4 = pBuffer[Pos(i ,j-1)]; a5 = pBuffer[Pos(i ,j+1)]; a6 = pBuffer[Pos(i-1,j-1)]; a7 = pBuffer[Pos(i-1,j )]; a8 = pBuffer[Pos(i-1,j+1)]; if (a1+a2+a3+a4+a5+a6+a7+a8 == 255*8) pTemp[Pos(i,j)] = 0; } } } memcpy(pBuffer, pTemp, Height*Width*sizeof(BYTE)); delete []pTemp; } /************************************************************************/ /* 函数:轮廓跟踪; 说明:显示整张图像的轮廓 */ /************************************************************************/ void CDibImage::OutlineTrack(BYTE *pBuffer, int Height, int Width) { int i,j; int pixel;//像素值 bool bFindStartPoint;//是否找到起始点及回到起始点 bool bFindPoint;//是否扫描到一个边界点 Point StartPoint,CurrentPoint;//起始边界点与当前边界点 int Direction[8][2]={{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1},{-1,0}};//八个方向和起始扫描方向 int BeginDirect; //将图像二值化 ////////////////白目标物,黑背景 for (i=0;i<Height;i++) { for(j=0;j<Width;j++) { if(pBuffer[Pos(i,j)] > 200) pBuffer[Pos(i,j)] = 255; else pBuffer[Pos(i,j)] = 0; } } BYTE *pTemp = new BYTE[Height*Width*sizeof(BYTE)];//创建缓冲区,将二值化后的图像数据赋给该缓冲区 memcpy(pTemp,pBuffer,Height*Width*sizeof(BYTE)); bFindStartPoint = false;//先找到最左上方的边界点 for (j = 0;j < Height && !bFindStartPoint;j++) { for(i = 0;i < Width && !bFindStartPoint;i++) { pixel = pTemp[Pos(i,j)]; if(pixel == 255) //如果找到白点 { bFindStartPoint = true; StartPoint.Height = i; StartPoint.Width = j; pTemp[Pos(i,j)] = 255; } } } BeginDirect = 0;//由于起始点是在左下方,故起始扫描沿左上方向 bFindStartPoint = false;//跟踪边界 CurrentPoint.Height = StartPoint.Height;//从初始点开始扫描 CurrentPoint.Width = StartPoint.Width; while(!bFindStartPoint) { bFindPoint = false; while(!bFindPoint) { //沿扫描方向查看一个像素 i = CurrentPoint.Height + Direction[BeginDirect][1]; j = CurrentPoint.Width + Direction[BeginDirect][0]; pixel = pTemp[Pos(i,j)]; if(pixel== 255) { bFindPoint = true; CurrentPoint.Height = CurrentPoint.Height + Direction[BeginDirect][1]; CurrentPoint.Width = CurrentPoint.Width + Direction[BeginDirect][0]; if(CurrentPoint.Height == StartPoint.Height && CurrentPoint.Width == StartPoint.Width) bFindStartPoint = true; i = CurrentPoint.Height; j = CurrentPoint.Width; pTemp[Pos(i,j)] = 255; BeginDirect--;//扫描的方向逆时针旋转两格 if(BeginDirect == -1) BeginDirect = 7; BeginDirect--; if(BeginDirect == -1) BeginDirect = 7; } else { //扫描方向顺时针旋转一格 BeginDirect++; if(BeginDirect == 8) BeginDirect = 0; } } } memcpy(pBuffer, pTemp, Height*Width*sizeof(BYTE)); // 复制图像 delete []pTemp; // 释放内存 } /************************************************************************/ /* 函数:图像测量——图像区域标记; 说明:标记出图像中的连通区域; */ /************************************************************************/ void CDibImage::MeasureBiaoJi(BYTE *pBuffer, int Height, int Width) //对图像区域进行标记 { int i,j; //循环变量 int x_sign=0; int m_temp=0; int x_temp=0; int y_temp=0; int stop=0; int flag[255]; memset(flag,0,255); BYTE *pTemp=new BYTE[Height*Width*sizeof(BYTE)];//开辟一个临时内存区 memset(pTemp, 255, Height*Width*sizeof(BYTE)); //从左到右标号 for(i=1;i<Height-1;i++) // 每行 { if(stop==1)//判断连通区是否太多 break; for(j=1;j<Width-1;j++) // 每列 { if(x_sign>250) { AfxMessageBox("连通区数目太多,请增大阈值!"); stop=1; break; } if(pBuffer[Pos((Height-i-1),j)] == 0)//若当前点为黑点 { if(pBuffer[Pos((Height-i-1+1),j+1)] == 0)//右上 { pTemp[Pos((Height-i-1),j)] = pTemp[Pos((Height-i-1+1),j+1)]; x_temp=pTemp[Pos((Height-i-1+1),j+1)]; flag[x_temp]+=1; //左前 if(pBuffer[Pos((Height-i-1),j-1)] == 0 && pTemp[Pos((Height-i-1),j-1)] != x_temp) { y_temp=pTemp[Pos((Height-i-1),j-1)]; for(int m=1;m<=Height-1;m++) for(int n=1;n<=Width-1;n++) { if(pTemp[Pos((Height-m-1),n)] == y_temp) { flag[y_temp]=0; pTemp[Pos((Height-m-1),n)]=x_temp; flag[x_temp]+=1; } } }//end//左前 //左上 if(pBuffer[Pos((Height-i-1+1),j-1)] == 0 && pTemp[Pos((Height-i-1+1),j-1)] != x_temp) { y_temp=pBuffer[Pos((Height-i-1+1),j-1)]; for(int m=1;m<=Height-1;m++) for(int n=1;n<=Width-1;n++) { if(pTemp[Pos((Height-m-1),n)] == y_temp) { flag[y_temp]=0; pTemp[Pos((Height-m-1),n)]=x_temp; flag[x_temp]+=1; } } }//end//左上 } else if(pBuffer[Pos((Height-i-1+1), j)]==0)//正上 { pTemp[Pos((Height-i-1), j)] = pTemp[Pos((Height-i-1+1), j)]; x_temp = pTemp[Pos((Height-i-1+1), j)]; flag[x_temp]+=1; } else if(pBuffer[Pos((Height-i-1+1), j-1)] == 0)//左上 { pTemp[Pos((Height-i-1), j)]=pTemp[Pos((Height-i-1+1), j-1)]; x_temp = pTemp[Pos((Height-i-1+1), j-1)]; flag[x_temp]+=1; } else if(pBuffer[Pos((Height-i-1), j-1)] == 0)//左前 { pTemp[Pos((Height-i-1), j)]=pTemp[Pos((Height-i-1), j-1)]; x_temp=pTemp[Pos((Height-i-1), j-1)]; flag[x_temp]+=1; } else//没有 { ++x_sign; m_temp=x_sign; pTemp[Pos((Height-i-1), j)] = m_temp; flag[m_temp]=1; } }//end if }// 每列 }//end 每行 }