⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 grayproc.cpp

📁 基于视觉的道路识别技术的智能小车导航源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// 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 + -