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

📄 edgecontour.cpp

📁 集装箱号码演示程序1.0完美版本
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	//起始边界点与当前边界点
	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;

	// 计算图像每行的字节数
	lLineBytes = WIDTHBYTES(lWidth * 8);

	// 暂时分配内存,以保存新图像
	hNewDIBBits = LocalAlloc(LHND, lLineBytes * lHeight);

	if (hNewDIBBits == NULL)
	{
		// 分配内存失败
		return FALSE;
	}
	
	// 锁定内存
	lpNewDIBBits = (char * )LocalLock(hNewDIBBits);

	// 初始化新分配的内存,设定初始值为255
	lpDst = (char *)lpNewDIBBits;
	memset(lpDst, (BYTE)255, lLineBytes * lHeight);

	//先找到最左上方的边界点
	bFindStartPoint = false;
	for (j = 0;j < lHeight && !bFindStartPoint;j++)
	{
		for(i = 0;i < lWidth && !bFindStartPoint;i++)
		{
			// 指向源图像倒数第j行,第i个象素的指针			
			lpSrc = (char *)lpDIBBits + lLineBytes * j + i;
			
			//取得当前指针处的像素值,注意要转换为unsigned char型
			pixel = (unsigned char)*lpSrc;
			
			if(pixel == 0)
			{
				bFindStartPoint = true;

				StartPoint.Height = j;
				StartPoint.Width = i;

				// 指向目标图像倒数第j行,第i个象素的指针			
				lpDst = (char *)lpNewDIBBits + lLineBytes * j + i;	
				*lpDst = (unsigned char)0;
			}		
		}
	}

	//由于起始点是在左下方,故起始扫描沿左上方向
	BeginDirect = 0;
	//跟踪边界
	bFindStartPoint = false;
	//从初始点开始扫描
	CurrentPoint.Height = StartPoint.Height;
	CurrentPoint.Width = StartPoint.Width;
	while(!bFindStartPoint)
	{
		bFindPoint = false;
		while(!bFindPoint)
		{
			//沿扫描方向查看一个像素
			lpSrc = (char *)lpDIBBits + lLineBytes * ( CurrentPoint.Height + Direction[BeginDirect][1])
				+ (CurrentPoint.Width + Direction[BeginDirect][0]);
			pixel = (unsigned char)*lpSrc;
			if(pixel == 0)
			{
				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;
				}
				lpDst = (char *)lpNewDIBBits + lLineBytes * CurrentPoint.Height + CurrentPoint.Width;
				*lpDst = (unsigned char)0;
				//扫描的方向逆时针旋转两格
				BeginDirect--;
				if(BeginDirect == -1)
					BeginDirect = 7;
				BeginDirect--;
				if(BeginDirect == -1)
					BeginDirect = 7;
			}
			else
			{
				//扫描方向顺时针旋转一格
				BeginDirect++;
				if(BeginDirect == 8)
					BeginDirect = 0;

			}

		}
	}

	// 复制腐蚀后的图像
	memcpy(lpDIBBits, lpNewDIBBits, lWidth * lHeight);

	// 释放内存
	LocalUnlock(hNewDIBBits);
	LocalFree(hNewDIBBits);

	// 返回
	return TRUE;
}

/*************************************************************************
 *
 * 函数名称:
 *   MyDIB()
 *
 * 参数:
 *   LPSTR lpDIBBits    - 指向源DIB图像指针
 *   LONG  lWidth       - 源图像宽度(象素数,必须是4的倍数)
 *   LONG  lHeight      - 源图像高度(象素数)
 * 返回值:
 *   BOOL               - 边缘检测成功返回TRUE,否则返回FALSE。
 *
 * 说明:
 * 该函数用水平边缘检测算子对图像进行边缘检测运算。
 * 
 * 要求目标图像为灰度图像。
 ************************************************************************/

BOOL WINAPI MyDIB(LPSTR lpDIBBits, LONG lWidth, LONG lHeight)
{
	
	// 指向缓存图像的指针
	LPSTR	lpDst1;
	LPSTR	lpDst2;
	
	// 指向缓存DIB图像的指针
	LPSTR	lpNewDIBBits1;
	HLOCAL	hNewDIBBits1;
	LPSTR	lpNewDIBBits2;
	HLOCAL	hNewDIBBits2;

	//循环变量
	long i;
	long j;

	// 模板高度
	int		iTempH;
	
	// 模板宽度
	int		iTempW;
	
	// 模板系数
	FLOAT	fTempC;
	
	// 模板中心元素X坐标
	int		iTempMX;
	
	// 模板中心元素Y坐标
	int		iTempMY;
	
	//模板数组
	FLOAT aTemplate[9];

	// 暂时分配内存,以保存新图像
	hNewDIBBits1 = LocalAlloc(LHND, lWidth * lHeight);

	if (hNewDIBBits1 == NULL)
	{
		// 分配内存失败
		return FALSE;
	}
	
	// 锁定内存
	lpNewDIBBits1 = (char * )LocalLock(hNewDIBBits1);

	// 暂时分配内存,以保存新图像
	hNewDIBBits2 = LocalAlloc(LHND, lWidth * lHeight);

	if (hNewDIBBits2 == NULL)
	{
		// 分配内存失败
		return FALSE;
	}
	
	// 锁定内存
	lpNewDIBBits2 = (char * )LocalLock(hNewDIBBits2);

	// 拷贝源图像到缓存图像中
	lpDst1 = (char *)lpNewDIBBits1;
	memcpy(lpNewDIBBits1, lpDIBBits, lWidth * lHeight);
	lpDst2 = (char *)lpNewDIBBits2;
	memcpy(lpNewDIBBits2, lpDIBBits, lWidth * lHeight);


	// 设置Prewitt模板参数
	iTempW = 3;
	iTempH = 3;
	fTempC = 1.0;
	iTempMX = 1;
	iTempMY = 1;
	aTemplate[0] = 0.0;
	aTemplate[1] = 0.0;
	aTemplate[2] = 0.0;
	aTemplate[3] = -1.0;
	aTemplate[4] = 1.0;
	aTemplate[5] = 0.0;
	aTemplate[6] = 0.0;
	aTemplate[7] = 0.0;
	aTemplate[8] = 0.0;

	// 调用Template()函数
	if (!Template(lpNewDIBBits1, lWidth, lHeight, 
		iTempH, iTempW, iTempMX, iTempMY, aTemplate, fTempC))
	{
		return FALSE;
	}

	// 设置Prewitt模板参数
	aTemplate[0] = 0.0;
	aTemplate[1] = -1.0;
	aTemplate[2] = 0.0;
	aTemplate[3] = 0.0;
	aTemplate[4] = 1.0;
	aTemplate[5] = 0.0;
	aTemplate[6] = 0.0;
	aTemplate[7] = 0.0;
	aTemplate[8] = 0.0;

	// 调用Template()函数
	if (!Template(lpNewDIBBits2, lWidth, lHeight, 
		iTempH, iTempW, iTempMX, iTempMY, aTemplate, fTempC))
	{
		return FALSE;
	}

	//求两幅缓存图像的最大值
	for(j = 0; j <lHeight; j++)
	{
		for(i = 0;i <lWidth-1; i++)
		{

			// 指向缓存图像1倒数第j行,第i个象素的指针			
			lpDst1 = (char *)lpNewDIBBits1 + lWidth * j + i;

			// 指向缓存图像2倒数第j行,第i个象素的指针			
			lpDst2 = (char *)lpNewDIBBits2 + lWidth * j + i;
			
			if(*lpDst2 > *lpDst1)
				*lpDst1 = *lpDst2;
		
		}
	}

	// 复制经过模板运算后的图像到源图像
	memcpy(lpDIBBits, lpNewDIBBits1, lWidth * lHeight);

	// 释放内存
	LocalUnlock(hNewDIBBits1);
	LocalFree(hNewDIBBits1);

	LocalUnlock(hNewDIBBits2);
	LocalFree(hNewDIBBits2);
	// 返回
	return TRUE;
}

BOOL WINAPI myTemplate(LPSTR lpDIB)			
{
	// 指向复制图像的指针
	LPSTR	lpNewDIBBits;
	HLOCAL	hNewDIBBits;
	
	// 指向要复制区域的指针
	unsigned char*	lpDst;
	
	LPSTR lpDIBBits;                   //指向DIB的象素的指针
	
    LONG lLineBytes;                   // 图像每行的字节数
	unsigned char * lpSrc;             //指向原图像象素点的指针
	
    long lWidth;                       //图像宽度和高度
	long lHeight;
	
	// 计算结果
	INT	fResult;
	
	// 找到DIB图像象素起始位置
	lpDIBBits = ::FindDIBBits(lpDIB);
	lWidth = ::DIBWidth(lpDIB);   //DIB 宽度
	lHeight = ::DIBHeight(lpDIB); //DIB 高度
	
	// 计算图像每行的字节数
	lLineBytes = WIDTHBYTES(lWidth * 8);
	
	// 暂时分配内存,以保存新图像
	hNewDIBBits = LocalAlloc(LHND, lLineBytes * lHeight);
	
	// 判断是否内存分配失败
	if (hNewDIBBits == NULL)
	{
		// 分配内存失败
		return false;
	}
	
	// 锁定内存
	lpNewDIBBits = (char * )LocalLock(hNewDIBBits);
	
	// 初始化图像为原始图像
	memcpy(lpNewDIBBits, lpDIBBits, lLineBytes * lHeight);
	
	
	long i,j;           //循环变量
	
	//
	//
	for(i = 0; i < lHeight-1; i++)
	{
		// 每列
		for(j = 0; j < lWidth-1; j++)
		{
			// 指向新DIB第i行,第j个象素的指针
			lpDst = (unsigned char*)lpNewDIBBits + lLineBytes * (lHeight - 1 - i) + j;
			
			// 指向DIB第i行,第j个象素的指针
			lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) + j;
			
			fResult=(*lpSrc)-(*(lpSrc+1));
			
			// 取绝对值
			if(fResult<0) fResult=-fResult;
			
			// 判断是否超过255
			if(fResult > 255)
			{
				// 直接赋值为255
				* lpDst = 255;
			}
			else
			{
				// 赋值
				* lpDst = (unsigned char) (fResult + 0.5);
			}
			
		}
	}
	
	// 复制变换后的图像
	memcpy(lpDIBBits, lpNewDIBBits, lLineBytes * lHeight);
	
	// 释放内存
	LocalUnlock(hNewDIBBits);
	LocalFree(hNewDIBBits);
	
	// 返回
	return TRUE;
	
}

HDIB WINAPI myCropDIB(HDIB hDIB, LPRECT lpRect)
{
	
	LPBITMAPINFO lpbmi = NULL; 
    LPBYTE       lpSourceBits, lpTargetBits, lpResult; 
    HDC			 hDC = NULL, hSourceDC, hTargetDC; 
    HBITMAP      hSourceBitmap, hTargetBitmap, hOldTargetBitmap, hOldSourceBitmap; 
    DWORD        dwSourceBitsSize, dwTargetBitsSize, dwTargetHeaderSize; 
	int			 nWidth, nHeight;
	HDIB		 hNewDIB;
	DWORD		 dwSize;
	
	// Get DIB pointer
	if (! hDIB)
	{
		return NULL;
	}
	LPBITMAPINFO lpSrcDIB = (LPBITMAPINFO)GlobalLock(hDIB);
	if (! lpSrcDIB)
	{
		return NULL;
	}
	
    // Allocate and fill out a BITMAPINFO struct for the new DIB 
    dwTargetHeaderSize = sizeof( BITMAPINFOHEADER ) + PaletteSize((LPSTR)lpSrcDIB); 
    lpbmi = (LPBITMAPINFO)malloc( dwTargetHeaderSize ); 
	memcpy(lpbmi, lpSrcDIB, dwTargetHeaderSize);
	nWidth = RECTWIDTH(lpRect);
	nHeight = RECTHEIGHT(lpRect);
    lpbmi->bmiHeader.biWidth = nWidth; 
    lpbmi->bmiHeader.biHeight = nHeight; 
	
    // Gonna use DIBSections and BitBlt() to do the conversion, so make 'em 
	hDC = ::GetDC( NULL ); 
    hTargetBitmap = CreateDIBSection( hDC, lpbmi, DIB_RGB_COLORS, (VOID **)&lpTargetBits, NULL, 0 ); 
    hSourceBitmap = CreateDIBSection( hDC, lpSrcDIB, DIB_RGB_COLORS, (VOID **)&lpSourceBits, NULL, 0 ); 
    hSourceDC = CreateCompatibleDC( hDC ); 
    hTargetDC = CreateCompatibleDC( hDC ); 
	
    // Flip the bits on the source DIBSection to match the source DIB 
    dwSourceBitsSize = lpSrcDIB->bmiHeader.biHeight * BytesPerLine((LPBYTE)&(lpSrcDIB->bmiHeader)); 
    dwTargetBitsSize = lpbmi->bmiHeader.biHeight * BytesPerLine((LPBYTE)&(lpbmi->bmiHeader)); 
    memcpy( lpSourceBits, FindDIBBits((LPSTR)lpSrcDIB), dwSourceBitsSize ); 
    lpbmi->bmiHeader.biSizeImage = dwTargetBitsSize; 
	
    // Select DIBSections into DCs 
    hOldSourceBitmap = (HBITMAP)SelectObject( hSourceDC, hSourceBitmap ); 
    hOldTargetBitmap = (HBITMAP)SelectObject( hTargetDC, hTargetBitmap ); 
	
	// put old bitmap in new bitmap 
    BitBlt(hTargetDC, 0, 0, nWidth, nHeight, hSourceDC, lpRect->left, lpRect->top, SRCCOPY); 
	
    // Clean up and delete the DCs 
    SelectObject( hSourceDC, hOldSourceBitmap ); 
    SelectObject( hTargetDC, hOldTargetBitmap ); 
    DeleteDC( hSourceDC ); 
    DeleteDC( hTargetDC ); 
    ::ReleaseDC( NULL, hDC ); 
	
    // Flush the GDI batch, so we can play with the bits 
    GdiFlush(); 
	
    // Allocate enough memory for the new CF_DIB, and copy bits 
	dwSize = dwTargetHeaderSize + dwTargetBitsSize;
	hNewDIB =(HDIB)GlobalAlloc(GHND, dwSize);
    lpResult = (LPBYTE)GlobalLock(hNewDIB);//malloc( dwTargetHeaderSize + dwTargetBitsSize ); 
    memcpy( lpResult, lpbmi, dwTargetHeaderSize ); 
    memcpy( FindDIBBits( (LPSTR)lpResult ), lpTargetBits, dwTargetBitsSize ); 
	
    // final cleanup 
    DeleteObject( hTargetBitmap ); 
    DeleteObject( hSourceBitmap ); 
    free( lpbmi ); 
	GlobalUnlock(hDIB);
	GlobalUnlock(hNewDIB);
	
    return hNewDIB;
}

BOOL WINAPI myHprojectDIB(LPSTR lpDIB, LONG lWidth, LONG lHeight, 
						  int* iTop, int* iBottom) 
{
	LPSTR lpDIBBits;                   //指向DIB的象素的指针
	
    LONG lLineBytes;                   // 图像每行的字节数
	unsigned char * lpSrc;             //指向原图像象素点的指针
	
	unsigned char pixel;				//像素值
	
	int i,j;
	
	// 计算结果
	INT* iResult;
	
	INT pzBottom,pzTop;
	
	bool findPZ=false;
	
	// 找到DIB图像象素起始位置
	lpDIBBits = ::FindDIBBits(lpDIB);
	
	// 计算图像每行的字节数
	lLineBytes = WIDTHBYTES(lWidth * 8);
	
	iResult=new INT[lHeight];
	
	for(i=0;i<lHeight;i++)
		iResult[i]=0;
	
	for(j=lHeight/5;j<lHeight*0.8;j++)
	{
		iResult[j]=0;
		for(i=0;i<lWidth;i++)
		{
			lpSrc=(unsigned char*)lpDIBBits+lLineBytes*j+i;
			pixel=(unsigned char)(*lpSrc);
			if(pixel==255)
			{
				iResult[j]++;
			}
		}
		if((!findPZ)&&iResult[j]>25)
		{
			pzBottom=j;
			findPZ=true;
		}
		if(findPZ&&iResult[j]<25)
		{
			pzTop=j;
			break;
		}
		
	}
	pzTop=pzBottom+35;
	pzBottom=pzBottom-20;   //微量调整
	*iBottom=lHeight-pzBottom;
	*iTop=lHeight-pzTop;
	return true;
}

BOOL WINAPI myVprojectDIB(LPSTR lpDIB, LONG lWidth, LONG lHeight, 
						  int* iLeft, int* iRight) 
{
	LPSTR lpDIBBits;                   //指向DIB的象素的指针
	
    LONG lLineBytes;                   // 图像每行的字节数
	unsigned char * lpSrc;             //指向原图像象素点的指针
	
	unsigned char pixel;				//像素值
	
	int i,j;
	
	// 计算结果
	INT* iResult;
	
	INT pzLeft,pzRight;
	
	bool findPZ=false;
	
	// 找到DIB图像象素起始位置
	lpDIBBits = ::FindDIBBits(lpDIB);
	
	// 计算图像每行的字节数
	lLineBytes = WIDTHBYTES(lWidth * 8);
	
	iResult=new INT[lWidth];
	
	for(i=0;i<lWidth;i++)
		iResult[i]=0;
	
	for(i=lWidth/5;i<lWidth*0.8;i++)
	{
		iResult[i]=0;
		for(j=0;j<lHeight;j++)
		{
			lpSrc=(unsigned char*)lpDIBBits+lLineBytes*j+i;
			pixel=(unsigned char)(*lpSrc);
			if(pixel==255)
			{
				iResult[i]++;
			}
		}
		if((!findPZ)&&iResult[i]>10)
		{
			pzLeft=i;
			findPZ=true;
		}
		pzRight=pzLeft+300;
	}
	
	*iLeft=pzLeft-40;
	*iRight=pzRight+10;
	return true;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -