// ImgProcess.cpp: implementation of the CImgProcess class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "ImgProcess.h"
#include <stdio.h>
#include <queue>
#include <math.h>
#define _EdgeAll 0;
#define _EdgeH 1;
#define _EdgeV 2;
#define _EdgeCW 3;
#define _EdgeCCW 4;
#define PI 3.1415926
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
void printd(FILE*p, double *a);
void printi(FILE*p, int *a);
//常用模板数组
// 平均平滑 1/9
float Template_Smooth_Avg[9]={1, 1, 1,
1, 1, 1,
1, 1, 1};
// Gauss平滑 1/16
float Template_Smooth_Gauss[9]={1, 2, 1,
2, 4, 2,
1, 2, 1};
// Sobel垂直边缘检测
float Template_HSobel[9]={-1, 0, 1,
-2, 0, 2,
-1 ,0 , 1};
// Sobel水平边缘检测
float Template_VSobel[9]={-1, -2, -1,
0, 0, 0,
1, 2, 1};
// LOG边缘检测
float Template_Log[25]={0, 0, -1, 0, 0,
0, -1, -2, -1, 0,
-1, -2, 16, -2, -1,
0, -1, -2, -1, 0,
0, 0, -1, 0, 0};
//Sigma = 2,较平滑
double Template_Log1[25]={0.0448, 0.0468, 0.0564, 0.0468, 0.0448,
0.0468, 0.3167, 0.7146, 0.3167, 0.0468,
0.0564, 0.7146, -4.9048, 0.7146, 0.0564,
0.0468, 0.3167, 0.7146, 0.3167, 0.0468,
0.0448, 0.0468, 0.0564, 0.0468, 0.0448
};
// Laplacian边缘检测
float Template_Laplacian1[9] = {0, -1, 0,
-1, 4, -1,
0, -1, 0
};
float Template_Laplacian2[9] = {-1, -1, -1,
-1, 8, -1,
-1, -1, -1
};
// DCT量化数组
int Quant_table[8][8]=
{16,11,10,16,24,40,51,61,
12,12,14,19,26,58,60,55,
14,13,16,24,40,57,69,56,
14,17,22,29,51,87,80,62,
18,22,37,56,68,109,103,77,
24,35,55,64,81,104,113,92,
49,64,78,87,103,121,120,101,
72,92,95,98,112,100,103,99};
// Z形扫描表格
int ZTable[8][8]={ 0,1,5,6,14,15,27,28,
2,4,7,13,16,26,29,42,
3,8,12,17,25,30,41,43,
9,11,18,24,31,40,44,53,
10,19,23,32,39,45,52,54,
20,22,33,38,46,51,55,60,
21,34,37,47,50,56,59,61,
35,36,48,49,57,58,62,63
};
// 带参构造函数
CImgProcess::CImgProcess()
{
m_nBasePt = 4;
}
CImgProcess::~CImgProcess()
{
}
/**************************************************
void CImgProcess::AutoThreshold(CImgProcess *pTo)
功能:
图像的自动阈值化
参数:
CImgProcess * pTo
输出CImgProcess对象的指针
返回值:
无
***************************************************/
void CImgProcess::AutoThreshold(CImgProcess *pTo)
{
//int nDiffGray;
//int nThres = DetectThreshold(100, nDiffGray);//取得分割阈值,最大迭代次数为100
//Threshold(pTo, nThres); //阈值分割
int dDiffGray;
int nThres = DetectThreshold(100, dDiffGray);
Threshold(pTo, nThres);
}
/*******************
void CImgProcessProcessing::Erode(CImgProcess* pTo, int se[3][3])
功能:
3*3结构元素的二值图像腐蚀运算
注:
只能处理2值图象
参数:
ImgProcess* pTo: 目标输出图像的 CImgProcess 指针
se[3][3]: 3*3的结构元素,其数组元素的合法取值为:
1 --- 前景
0 --- 背景
-1 --- 不关心
返回值:
无
*******************/
void CImgProcess::Erode(CImgProcess *pTo, int se[3][3])
{
int nHeight = GetHeight();
int nWidth = GetWidthPixel();
int i, j; //图像循环变量
int k, l; //结构元素循环变量
BOOL bMatch; //结构元素是否与局部图像匹配
pTo->InitPixels(255); //清空目标输出图像
//逐行扫描图像,为防止访问越界,四周留出一个像素宽的空边
for(i=1; i<nHeight-1; i++)
{
for(j=1; j<nWidth-1; j++)
{
//由于使用的是3*3的结构元素,为防止越界,不处理最上和最下的两行像素以及最左和最右的两列像素
bMatch = true;
for(k=0; k<3; k++)
{
for(l=0; l<3; l++)
{
if( se[k][l] == -1 ) //不关心
continue;
if( se[k][l] == 1 ) //前景
{
if( GetGray(j-1+l, i-1+k) != 0 )
{
bMatch = false;
break;
}
}
else if( se[k][l] == 0 ) //背景
{
if( GetGray(j-1+l, i-1+k) != 255 )
{
bMatch = false;
break;
}
}
else
{
AfxMessageBox("结构元素含有非法值!请检查后重新设定。");
return;
}
}//for l
}//for k
if( bMatch )
pTo->SetPixel(j, i, RGB(0, 0, 0));
}// for j
}// for i
//int nheight = GetHeight();
//int nwidth = GetWidthPixel();
//int i, j, k, l;
//bool bMatch;
//pTo->SetPixel(255);
//for (i = 1; i < nheight;i++)
//{
// for (j = 1; j < nwidth;j++)
// {
// bMatch = true;
// for (int k = 0; k < 3;k++)
// {
// for (int l = 0; l < 3;l++)
// {
// if (se[k][l]==-1)//不关心
// {
// continue;
// }
// if (se[k][l] == 1)//前景
// {
// if (GetGray(j-1+l,i-1+k)!=0)//只要有一个不符合,就职位false
// {
// bMatch = false;
// break;
// }
// }
// else if (se[k][l]==0)//背景
// {
// if (GetGray(j - 1 + l, i - 1 + k) != 255)
// {
// bMatch = false;
// break;
// }
// }
// else
// {
// AfxMessageBox("结构元素含有非法值,请检查后重新输入");
// return;
// }
// }
// }
// if (bMatch)
// {
// pTo->SetPixel(j, i, RGB(0,0,0));//
// }
// }
//}
}
/*******************
void CImgProcess::Dilate(CImgProcess* pTo, int se[3][3])
功能:
3*3结构元素的二值图像膨胀运算
注:
只能处理2值图象
参数:
Image* pTo: 目标输出图像的 CImgProcess 指针
se[3][3]: 3*3的结构元素,其数组元素的合法取值为:
1 --- 前景
-1 --- 不关心
返回值:
无
*******************/
void CImgProcess::Dilate(CImgProcess *pTo, int se[3][3])
{
int nHeight = GetHeight();
int nWidth = GetWidthPixel();
int i, j; //图像循环变量
int k, l; //结构元素循环变量
//计算se关于中心的对称集
/*int nTmp;
for(i=0; i<2; i++)
{
for(j=0; j<3-i; j++)
{
nTmp = se[i][j];
se[i][j] = se[2-i][2-j];
se[2-i][2-j] = nTmp;
}
}*/
//先计算反射集
int nTemp;
for (i = 0; i < 2;i++)
{
for (j = 0; j < 3 - i;j++)
{
nTemp = se[i][j];
se[i][j] = se[2 - i][2 - j];
se[2 - i][2 - j] = nTemp;
}
}
pTo->InitPixels(255); //清空目标输出图像
//逐行扫描图像,为防止访问越界,四周留出一个像素宽的空边
for(i=1; i<nHeight-1; i++)
{
for(j=1; j<nWidth-1; j++)
{
//由于使用的是3*3的结构元素,为防止越界,不处理最上和最下的两行像素以及最左和最右的两列像素
for(k=0; k<3; k++)
{
for(l=0; l<3; l++)
{
if( se[k][l] == -1 ) // 不关心
continue;
if( se[k][l] == 1 )//前景
{
//if( GetGray(j-1+l, i-1+k) == 0)//只要有交集就职位0
//{
// //原图中对应结构元素的局部区域有一点为1,就将目标图像对应于结构元素中心的像素置0
// pTo->SetPixel(j, i, RGB(0, 0, 0));
// break;
//}
if (GetGray(j - 1 + l, i - 1 + k) == 0)
{
pTo->SetPixel(j, i, RGB(0,0,0));
break;
}
}
else
{
AfxMessageBox("结构元素含有非法值!请检查后重新设定。");
return;
}
}//for l
}//for k
}// for j
}// for i
}
/*******************
void CImgProcessProcessing::Open(CImgProcess* pTo, int se[3][3])
功能:
3*3结构元素的二值图像开运算
注:
只能处理2值图象
参数:
Image* pTo: 目标输出图像的 CImgProcess 指针
se[3][3]: 3*3的结构元素,其数组元素的合法取值为:
1 --- 前景
-1 --- 不关心
返回值:
无
*******************/
void CImgProcess::Open(CImgProcess* pTo, int se[3][3])
{
/*pTo->InitPixels(255);
Erode(pTo, se);
*this = *pTo;
Dilate(pTo, se);*/
pTo->InitPixels(255);
Erode(pTo, se);//传2维数组名即可
CImgProcess tempimg = *pTo;
tempimg.Dilate(pTo, se);
}
/*******************
void CImgProcessProcessing::Close(CImgProcess* pTo, int se[3][3])
功能:
3*3结构元素的二值图像闭运算
注:
只能处理2值图象
参数:
Image* pTo: 目标输出图像的 CImgProcess 指针
se[3][3]: 3*3的结构元素,其数组元素的合法取值为:
1 --- 前景
-1 --- 不关心
返回值:
无
*******************/
void CImgProcess::Close(CImgProces