📄 grayproc.cpp
字号:
// GrayProc.cpp : 实现文件
#include "stdafx.h"
#include "GrayProc.h"
#include <math.h>
#include"VideoPro.h"
#include "HSI.h"
#include <TIME.H>
#define MAX2(x1,x2) (x1>x2?x1:x2)
#define MAX3(x1,x2,x3) (MAX2(x1,x2)>MAX2(x2,x3)?MAX2(x1,x2):MAX2(x2,x3))
#define MIN2(x1,x2) (x1<x2?x1:x2)
#define MIN3(x1,x2,x3) (MIN2(x1,x2)<MIN2(x2,x3)?MIN2(x1,x2):MIN2(x2,x3))
#define MID3(x1,x2,x3) (x1+x2+x3-MAX3(x1,x2,x3)-MIN3(x1,x2,x3))
#define SOLID 0
#define SPACE 255
//#define DEBUG
//static int Tag=0;
CGrayProc::CGrayProc()
{
}
CGrayProc::~CGrayProc()
{
}
// CGrayProc 成员函数
//反色变换
void CGrayProc::PointInVert(HDIB hDIB)
{
if(hDIB==NULL)
{
AfxMessageBox("没有相关的位图!");
return;
}
CDIB DIBtemp;
LPBYTE lpDIB,lpDIBBits;
lpDIB=(LPBYTE)::GlobalLock((HGLOBAL)hDIB);
lpDIBBits=DIBtemp.FindDIBBits (lpDIB);
if(DIBtemp.DIBBitCount (lpDIB)!=8)
{
MessageBox(NULL,"请将其转换为256色灰度位图,再处理!","系统提示",MB_ICONINFORMATION|MB_OK);
::GlobalUnlock((HGLOBAL)hDIB);
return;
}
LONG nWidthBytes;
nWidthBytes=WIDTHBYTES(DIBtemp.DIBWidth(lpDIB)*DIBtemp.DIBBitCount(lpDIB));
LONG lWidth=DIBtemp.DIBWidth(lpDIB);
LONG lHeight=DIBtemp.DIBHeight (lpDIB);
LONG x,y;
for(y=0;y<lHeight;y++)
{
for(x=0;x<lWidth;x++)
lpDIBBits[y*nWidthBytes+x]=255-lpDIBBits[y*nWidthBytes+x];
}
::GlobalUnlock((HGLOBAL)hDIB);
}
BOOL CGrayProc::GraySegLinTrans(HDIB hDIB, int nX1, int nY1, int nX2, int nY2)
{
if(hDIB==NULL)
{
AfxMessageBox("没有相关的位图!");
return FALSE;
}
CDIB DIBtemp;
LPBYTE lpDIB,lpDIBBits;
lpDIB=(LPBYTE)::GlobalLock((HGLOBAL)hDIB);
lpDIBBits=DIBtemp.FindDIBBits (lpDIB);
if(DIBtemp.DIBBitCount (lpDIB)!=8)
{
MessageBox(NULL,"请将其转换为256色灰度位图,再处理!","系统提示",MB_ICONINFORMATION|MB_OK);
::GlobalUnlock((HGLOBAL)hDIB);
return FALSE;
}
LONG nWidthBytes;
nWidthBytes=WIDTHBYTES(DIBtemp.DIBWidth(lpDIB)*DIBtemp.DIBBitCount(lpDIB));
LONG lWidth=DIBtemp.DIBWidth(lpDIB);
LONG lHeight=DIBtemp.DIBHeight (lpDIB);
LONG x,y;
BYTE byMap[256];
//计算灰度对应表
for(int i=0;i<=nX1;i++)
{
if(nX1>0)
{
byMap[i]=(BYTE)nY1*i/nX1;
}
else
{
byMap[i]=0;
}
}
for(;i<=nX2;i++)
{
if(nX2!=nX1)
{
byMap[i]=nY1+(BYTE)((nY2-nY1)*(i-nX1)/(nX2-nX1));
}
else
{
byMap[i]=nY1;
}
}
for(;i<256;i++)
{
if(nX2!=255)
{
byMap[i]=nY2+(BYTE)((255-nY2)*(i-nX2)/(255-nX2));
}
else
{
byMap[i]=255;
}
}
//灰度替换
for(y=0;y<lHeight;y++)
{
for(x=0;x<lWidth;x++)
lpDIBBits[y*nWidthBytes+x]=byMap[lpDIBBits[y*nWidthBytes+x]];
}
::GlobalUnlock((HGLOBAL)hDIB);
return 0;
}
//二值化
/*************************************************************************
*
* 函数名称:
* DIBHOLENUMBER()
*
* 参数:
* CDib * pDib - 指向CDib类的指针
*
* 返回值:
* BOOL - 成功返回True,否则返回False。
*
* 说明:
* 该函数将消去图象中面积小于阈值的小区域
*
*************************************************************************/
BOOL CGrayProc::HoleDetect(HDIB hDIB)
{
// 指向源图像的指针
LPBYTE lpSrc;
//图象的宽度和高度
LONG lWidth;
LONG lHeight;
//指向图像的指针
LPBYTE lpDIB=(LPBYTE)::GlobalLock((HGLOBAL)hDIB);
//得到图象的宽度和高度
// CSize SizeDim;
// SizeDim = pDib->GetDimensions();
lWidth = m_clsDIB.DIBWidth(lpDIB);
lHeight = m_clsDIB.DIBHeight(lpDIB);
//得到实际的Dib图象存储大小
// CSize SizeRealDim;
// SizeRealDim = hDIB->GetDibSaveDim();
// 计算图像每行的字节数
LONG lLineBytes = WIDTHBYTES(lWidth * 8); ;
//图像数据的指针
LPBYTE lpDIBBits = m_clsDIB.FindDIBBits(lpDIB);
// 循环变量
int i, j, s, n;
// 空穴的数目以及面积阈值
int nHoleNum, nMinArea;
int nBlackPix, temp;
// 正向和反向传播标志
int nDir1,nDir2;
// 用来存储的一位数组
int *pnBinary;
pnBinary =new int[lHeight*lLineBytes];
// 小区域的阈值面积为20个象素点
nMinArea = 30;
// 将图象二值化
for (j = 0; j < lHeight; j++)
{
for(i = 0; i < lWidth; i++)
{
// 指向源图像倒数第j行,第i个象素的指针
lpSrc = (unsigned char *)lpDIBBits + lLineBytes * j + i;
// 白色象素为背景,存成0
if(*lpSrc > 128)
{
pnBinary[lLineBytes * j + i] = 0;
}
// 黑色象素存成-1
else
{
pnBinary[lLineBytes * j + i] = -1;
}
}
}
// 空穴数赋初值
nHoleNum = 1;
do
{
s=0;
// 寻找每个空穴的初始象素值
for (j = 1; j < lHeight - 1; j++)
{
for(i = 1; i < lWidth - 1; i++)
{
// 找到初始象素
if(pnBinary[lLineBytes * j + i] == -1)
{
s = 1;
// 将象素值改成当前的空穴数值
pnBinary[lLineBytes * j + i] = nHoleNum;
// 跳出循环
j = lHeight;
i = lLineBytes;
}
}
}
//没有初始象素,跳出循环
if(s == 0)
break;
else
{
do
{
// 正向和反向传播系数赋初值0
nDir1 = 0;
nDir2 = 0;
// 正向扫描
for (j = 1; j < lHeight-1; j++)
{
for(i = 1; i < lWidth-1; i++)
{
nBlackPix = pnBinary[lLineBytes * j + i];
// 如果象素已经被扫描,或者是背景色,进行下一个循环
if(nBlackPix != -1)
continue;
// 如果上侧或者左侧的象素值已经被扫描,且属于当前的空穴,当前的象素值
// 改成空穴的数值
nBlackPix=pnBinary[lLineBytes * (j-1) + i];
if(nBlackPix == nHoleNum)
{
pnBinary[lLineBytes * j + i] = nHoleNum;
nDir1 = 1;
continue;
}
nBlackPix =pnBinary[lLineBytes * j + i - 1];
if(nBlackPix == nHoleNum)
{
pnBinary[lLineBytes * j + i] = nHoleNum;
nDir1 = 1;
}
}
}
// 正向象素全部被扫描,跳出循环
if(nDir1 == 0)
break;
// 反向扫描
for (j = lHeight-2; j >= 1 ; j--)
{
for(i = lWidth-2; i >= 1 ; i--)
{
nBlackPix = pnBinary[lLineBytes * j + i];
// 如果象素已经被扫描,或者是背景色,进行下一个循环
if(nBlackPix != -1)
continue;
// 如果下侧或者右侧的象素值已经被扫描,且属于当前的空穴,当前的象素值
// 改成空穴的数值
nBlackPix=pnBinary[lLineBytes * (j+1) + i];
if(nBlackPix == nHoleNum)
{
pnBinary[lLineBytes * j + i] = nHoleNum;
nDir2 = 1;
continue;
}
nBlackPix =pnBinary[lLineBytes * j + i + 1];
if(nBlackPix == nHoleNum)
{
pnBinary[lLineBytes * j + i] = nHoleNum;
nDir2 = 1;
}
}
}
if(nDir2 == 0)
break;
}
while(1);
}
// 空穴数增加
nHoleNum++;
}
while(1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -