图像处理:Robert边缘检测算子

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_33001647/article/details/84541634

事情比较多比较杂,早点把学校的事弄完吧,好久没写博客了,最近计算机前沿这门课,老师要布置课题,大部分是Verilog HDL程序设计,脑壳疼,硬件太烦,在这里插入图片描述
不过还好,可以选择其他方向的
在这里插入图片描述

哈哈,api学习还是有必要的,不必造轮子,不过,要有造轮子的能力,具体分的课题是边缘检测算法的Robert算子
在这里插入图片描述
书上只是给个函数,可以理解为伪代码,具体实现,还是要自己去动手的,书上只是给个思路而已:
在这里插入图片描述

核心就是对像素的处理,获取位图像素位,处理像素位,设置像素位,就这么几部,当初想,多么简单啊,其实还是不能大意,遇到一些问题,然后慢慢克服,最终解决难题,只有这样,才能不断成长,绝对不能眼高手低
主要遇到的问题,就是获得位图的像素位

一开始,我以为BITMAP结构的bmBits就是存放像素位的,结果运行有问题
在这里插入图片描述
还以为是我自己没有新加载一个位图,在新位图里存放新像素位,结果还是不行,调试时发现BITMAP的bmBits始终为0
在这里插入图片描述
所以问题出在这,我们并没有真正获取到位图的像素位,要获取位图的像素位,可以用GetBitmapBits函数,函数怎么用去查msdn或者百度
相应的设置像素位用SetBitmapBits,下面就是Robert算子具体实现的核心代码了
在这里插入图片描述

最后实现效果:
在这里插入图片描述
在这里插入图片描述
好了,大功告成,一定要注意,获取设置位图像素位,用BITMAP的bmBits成员是不行的,用GetBitmapBits和SetBitmapBits即可
最后附上完整win32 API代码:

//VC++图像处理程序
//图像的边缘检测-Robert算子
# include<windows.h>
# include<cmath>


LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);//窗口过程函数
void RobertOperator(HDC hdc, HDC hMemDc, HBITMAP hBitmap, int Width, int Height);
int WINAPI WinMain(HINSTANCE hInstance,
	HINSTANCE hPrevInstance,
	PSTR szCmdLine,
	int iCmdShow) 
{
	TCHAR szAppName[] = TEXT("Robert算子");

	//设计窗口类
	WNDCLASS wndclass;//窗口类
	wndclass.cbClsExtra = 0;
	wndclass.cbWndExtra = 0;
	wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);//窗口背景画刷(白色)
	wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
	wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
	wndclass.hInstance = NULL;
	wndclass.lpfnWndProc = WndProc;
	wndclass.lpszClassName = szAppName;//类名
	wndclass.lpszMenuName = NULL;
	wndclass.style = CS_HREDRAW | CS_VREDRAW;

	//注册窗口类
	if (!RegisterClass(&wndclass))
	{
		MessageBox(NULL, TEXT("Program requires windows NT!"), szAppName, MB_ICONERROR);
		return 0;
	}

	//创建窗口
	HWND hwnd = CreateWindow(szAppName,
		TEXT("Robert算子"),
		WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT,
		CW_USEDEFAULT,
	    540,
		630,
		NULL,
		NULL,
		hInstance,
		NULL);

	ShowWindow(hwnd, SW_SHOW);
	UpdateWindow(hwnd);

	MSG msg;//消息循环
	while (GetMessage(&msg, NULL, 0, 0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	

	return 0;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	static HDC hMemDc;
	static int xWidth, yHeight;
	static BITMAP bm;
	static HBITMAP hBitmap;

	switch (uMsg)
	{
	case WM_CREATE:
	{
		//原位图
		 hBitmap= (HBITMAP)LoadImage(NULL, TEXT("Picture2.bmp"), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
		if (hBitmap == NULL)
		{
			MessageBox(NULL, TEXT("读取图片失败"), TEXT("Error"), MB_ICONERROR);
			return 0;
		}

		//将原位图选进内存DC
		HDC hdc = GetDC(hwnd);
		hMemDc = CreateCompatibleDC(hdc);//内存DC
		SelectObject(hMemDc, hBitmap);
		ReleaseDC(hwnd, hdc);

		//计算位图的宽和高
		GetObject(hBitmap, sizeof(bm), &bm);
		xWidth = bm.bmWidth;
		yHeight = bm.bmHeight;
		return 0;
	}
	case WM_PAINT:
	{
		HDC hdc;
		PAINTSTRUCT ps;
		hdc = BeginPaint(hwnd, &ps);
		BitBlt(hdc, 0, 0, xWidth, yHeight, hMemDc, 0, 0, SRCCOPY);
		//BitBlt(hdc, 0, 300, xTempWidth, yTempHeight, hTempMemDc, 0, 0, SRCCOPY);
		RobertOperator(hdc, hMemDc,hBitmap,xWidth, yHeight);
		//BitBlt(hdc, 590, 0, xWidth, yHeight, hMemDc, 0, 0, SRCCOPY);
		EndPaint(hwnd, &ps);
		return 0;
	}
	case WM_CLOSE:
		DeleteDC(hMemDc);
		PostQuitMessage(0);
		//DestroyWindow(hwnd);
		return 0;
	}


	return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

void RobertOperator(HDC hdc, HDC hMemDc,HBITMAP hBitmap,int Width, int Height)
{
	

	int Robert_Pixel[4];//Robert算子
	
	
	BYTE *pTempPixel = new BYTE[16*Width*Height];
	//得到位图的像素位
	GetBitmapBits(hBitmap,16*Width*Height,(LPVOID)pTempPixel);
	
	BYTE *pPixel = new BYTE[16*Width*Height];
	for(int j=0;j<4*Height-1;j++)
		for (int i = 0; i < 4*Width - 1; i++)
		{
			//生成Robert算子
			Robert_Pixel[0] = pTempPixel[j*4*Width+i];
			Robert_Pixel[1] = pTempPixel[j*4*Width+ i + 1];
			Robert_Pixel[2] = pTempPixel[(j + 1)*4*Width+ i];
			Robert_Pixel[3] = pTempPixel[(j + 1)*4*Width+i + 1];

			//生成当前像素
			pPixel[j*4*Width+i] = (int)sqrt((Robert_Pixel[0] - Robert_Pixel[3])*
				(Robert_Pixel[0] - Robert_Pixel[3]) + (Robert_Pixel[1] - Robert_Pixel[2])*
				(Robert_Pixel[1] - Robert_Pixel[2]));
			//pPixel[j*Width + i] = pTempPixel[j*Width + i] + 100;

		}
	//设置新像素位
	SetBitmapBits(hBitmap,16* Width*Height,pPixel);
	BitBlt(hdc,0, 300, Width, Height, hMemDc, 0, 0, SRCCOPY);

}

注意相应的位图文件要放在工程目录下,以及位图的文件名

猜你喜欢

转载自blog.csdn.net/qq_33001647/article/details/84541634