数字图像处理实验总结(图像预处理)

  首先是边缘检测,加上原图像是图像锐化。函数

图像处理

直方图均衡:

直方图均衡:把原始图的直方图变换为均匀分布的形式,增长像素灰度值的动态范围,提升图像对比度。     spa

主要步骤:先统计各个像素占所有像素的比例,而后像素x的 直方图均衡后的像素值就是(x的比例+全部像素值比x小的比例)*255。实现图像均衡的结果。code

 

实验结果:orm

原图像:blog

直方图均衡后的图像:rem

代码:(是在MFC上实现的,课程祖传模板)string

void CDemoView::OnImagestretchingHistogramequalization()
{
	// TODO: 在此添加命令处理程序代码
	CDemoDoc *pDoc = GetDocument();
	HDIB dib = pDoc->GetHDIB();

	LPSTR	lpDIB = (LPSTR) ::GlobalLock((HGLOBAL)dib);
	int width = ::DIBWidth(lpDIB);
	int height = ::DIBHeight(lpDIB);
	LPBITMAPINFOHEADER phead = (LPBITMAPINFOHEADER)lpDIB;
	int biBitCount = phead->biBitCount / 8;
	if (biBitCount != 1)
	{
		::MessageBox(0, "ERROR!NOT GRAY LEVEL IMAGE!", NULL, MB_OK);
		::GlobalUnlock(dib);
		return;
	}
	int lineByte = (width * biBitCount + 3) / 4 * 4;
	unsigned char *lpDIBBits = (unsigned char *)::FindDIBBits(lpDIB);

	int palSize = ::PaletteSize((LPSTR)lpDIB);      //调色板尺寸
	HANDLE dibNew = ::GlobalAlloc(GHND, sizeof(BITMAPINFOHEADER) + palSize + height * lineByte);
	LPSTR lpDIBNew = (LPSTR) ::GlobalLock(dibNew);

	::memcpy((unsigned char*)lpDIBNew, (unsigned char*)lpDIB, sizeof(BITMAPINFOHEADER) + palSize + height * lineByte);
	unsigned char *lpDIBBitsNew = (unsigned char *)::FindDIBBits(lpDIBNew);
	int max = 0;
	int min = 255;
	int data;
	int  i, j;
	double pix[256];
	for (i = 0;i < 256;++i) {
		pix[i] = 0;
	}
	for (i = 0;i < height;i++) {
		for (j = 0;j < width;j++) {
			data = *(lpDIBBits + i * lineByte + j);
			pix[data]++;
		}
	}
	for (i = 1;i < 256;++i) {
		pix[i] = pix[i] + pix[i - 1];
	}
	for (i = 1;i < 256;++i) {
		pix[i] = pix[i]/width/height*255;
	}

	for (i = 0;i < height;i++) {
		for (j = 0;j < width;j++) {
			*(lpDIBBitsNew + i * lineByte + j) = (int)(pix[*(lpDIBBits + i * lineByte + j)] + 0.5);

		}
	}
	::GlobalUnlock(dib);
	::GlobalUnlock(dibNew);

	CMainFrame* pFrame = (CMainFrame *)(AfxGetApp()->m_pMainWnd);
	pFrame->SendMessage(WM_COMMAND, ID_FILE_NEW);

	CDemoView* pView = (CDemoView*)pFrame->MDIGetActive()->GetActiveView();
	CDemoDoc* pDocNew = pView->GetDocument();

	pDocNew->ReplaceHDIB((HDIB)dibNew);
	pDocNew->InitDIBData();
	pDocNew->UpdateAllViews(pView);
	Invalidate();
}

 

 

图像平滑: 

均值平滑:

中值平滑:

图像锐化:

 

laplace算子:it

图像校订:

采用参考点匹配来计算旋转参数:io

二维旋转能够用一下方程拟合:图像处理

u,v是原图像坐标。x,y是徐艳转后图像的坐标。

记下七组点的坐标,采用最小二乘法计算系数。

代码以下路所示:
函数采用了eigen库的矩阵Matrixxd模块, 其中七组点的数量根据交互的形式记在vector<int>pointvec

void CDemoView::OnLeastsquaremethodk()
{
	// TODO: 在此添加命令处理程序代码
	CDemoDoc *pDoc = GetDocument();
	HDIB dib = pDoc->GetHDIB();
	LPSTR	lpDIB = (LPSTR) ::GlobalLock((HGLOBAL)dib);
	int height = ::DIBHeight(lpDIB);
	int width = ::DIBWidth(lpDIB);


	LPBITMAPINFOHEADER phead = (LPBITMAPINFOHEADER)lpDIB;
	int biBitCount = phead->biBitCount / 8;
	
	int lineByte = (width * biBitCount + 3) / 4 * 4;
	unsigned char *lpDIBBits = (unsigned char *)::FindDIBBits(lpDIB);

	int palSize = ::PaletteSize((LPSTR)lpDIB);      //调色板尺寸
	HANDLE dibNew = ::GlobalAlloc(GHND, sizeof(BITMAPINFOHEADER) + palSize + height * lineByte);
	LPSTR lpDIBNew = (LPSTR) ::GlobalLock(dibNew);

	::memcpy((unsigned char*)lpDIBNew, (unsigned char*)lpDIB, sizeof(BITMAPINFOHEADER) + palSize );
	unsigned char *lpDIBBitsNew = (unsigned char *)::FindDIBBits(lpDIBNew);




	MatrixXd b1, b2;
	MatrixXd X=MatrixXd::Zero(7, 6);
	MatrixXd Y1= MatrixXd::Zero(7, 1);
	MatrixXd Y2 = MatrixXd::Zero(7, 1);
	if (pointVec.size() == 14) {
		for (int i = 0;i < 7;++i) {
			
			CPoint point = pointVec[i];
			point.y = height - point.y;
			X(i, 0) = 1;
			X(i, 1) = point.x;
			X(i, 2) = point.y;
			X(i, 3) = point.x*point.x;
			X(i, 4) = point.y*point.y;
			X(i, 5) = point.x*point.y;

		}
		for (int i = 7;i < 14;++i) {
			CPoint point = pointVec[i];
			point.y = height - point.y;
			Y1(i - 7, 0) = point.x;
			Y2(i - 7, 0) = point.y;
		}
		
	}
	MatrixXd tmp = (X.transpose()*X).inverse();
	b1 =tmp*X.transpose()*Y1;
	b2 = tmp * X.transpose()*Y2;
	CString string;
	pointVec.clear();
	string.Format("k100:%3f,k110:%3f,k101:%f,k120:%3f,k102:%3f,k111:%3f\nk200:%3f,k210:%3f,k201:%3f,k220:%3f,k202:%3f,k221:%3f",
		b1(0,0), b1(1, 0), b1(2, 0), b1(3, 0), b1(4, 0), b1(5, 0), b2(0, 0), b2(1, 0), b2(2, 0), b2(3, 0), b2(4, 0), b2(5, 0) );
	::MessageBox(0,string, "dataMessage", MB_OKCANCEL);
	for (int i = 0;i < height;++i) {
		for (int j = 0;j < width;++j) {
		
			for (int z = 0;z < biBitCount;++z) {
				
				*(lpDIBBitsNew + i * lineByte + j * biBitCount + z) = 0;
				
			}
		}

	}
	for (int i = 0;i < height;++i) {
		for (int j = 0;j < width;++j) {
				tmpdata(0, 0) = 1;
				tmpdata(0, 1) = j;
				tmpdata(0, 2) = i;
				tmpdata(0, 3) = j*j;
				tmpdata(0, 4) = i*i;
				tmpdata(0, 5) = i*j;
				float xnum = (tmpdata * b1).determinant();
				float ynum = (tmpdata * b2).determinant();
				int xint = (int)xnum;
				int yint = (int)ynum;

			for (int z = 0;z < biBitCount;++z) {
				if (xnum >= 0 && xnum < width&&ynum >= 0 && ynum <= height) {
					if (xnum >= 1 && xnum < width - 1 && ynum >= 1 && ynum <= height - 1)
						*(lpDIBBitsNew + i * lineByte + j * biBitCount + z) = *(lpDIBBits + yint * lineByte + xint * biBitCount + z)
						+ (*(lpDIBBits + (yint + 1) * lineByte + xint * biBitCount + z) - *(lpDIBBits + yint * lineByte + xint * biBitCount + z))*(ynum - yint)
						+ (*(lpDIBBits + yint * lineByte + (xint + 1) * biBitCount + z) - *(lpDIBBits + yint * lineByte + xint * biBitCount + z))*(xnum - xint)
						+ (*(lpDIBBits + (yint + 1) * lineByte + (xint + 1) * biBitCount + z) + *(lpDIBBits + yint * lineByte + xint * biBitCount + z)
							- *(lpDIBBits + (yint + 1) * lineByte + xint * biBitCount + z) - *(lpDIBBits + yint * lineByte + (xint + 1) * biBitCount + z))*(xnum - xint)*(ynum - yint);
					else
						*(lpDIBBitsNew + i * lineByte + j * biBitCount + z) = *(lpDIBBits + yint * lineByte + xint * biBitCount + z);
				}
			}
		}

	}
	::GlobalUnlock(dib);
	::GlobalUnlock(dibNew);

	CMainFrame* pFrame = (CMainFrame *)(AfxGetApp()->m_pMainWnd);
	pFrame->SendMessage(WM_COMMAND, ID_FILE_NEW);

	CDemoView* pView = (CDemoView*)pFrame->MDIGetActive()->GetActiveView();
	CDemoDoc* pDocNew = pView->GetDocument();

	pDocNew->ReplaceHDIB((HDIB)dibNew);
	pDocNew->InitDIBData();
	pDocNew->UpdateAllViews(pView);
	Invalidate();
}

 

大津阈值分割:最大方差分割:

代码以下:

void CDemoView::OnOtsuthresholdsegmentation()
{
	// TODO: 在此添加命令处理程序代码
	CDemoDoc *pDoc = GetDocument();
	HDIB dib = pDoc->GetHDIB();

	LPSTR	lpDIB = (LPSTR) ::GlobalLock((HGLOBAL)dib);
	int width = ::DIBWidth(lpDIB);
	int height = ::DIBHeight(lpDIB);
	LPBITMAPINFOHEADER phead = (LPBITMAPINFOHEADER)lpDIB;
	int biBitCount = phead->biBitCount / 8;
	if (biBitCount != 1)
	{
		::MessageBox(0, "ERROR!NOT GRAY LEVEL IMAGE!", NULL, MB_OK);
		::GlobalUnlock(dib);
		return;
	}
	int lineByte = (width * biBitCount + 3) / 4 * 4;
	unsigned char *lpDIBBits = (unsigned char *)::FindDIBBits(lpDIB);

	int palSize = ::PaletteSize((LPSTR)lpDIB);      //调色板尺寸
	HANDLE dibNew = ::GlobalAlloc(GHND, sizeof(BITMAPINFOHEADER) + palSize + height * lineByte);
	LPSTR lpDIBNew = (LPSTR) ::GlobalLock(dibNew);

	::memcpy((unsigned char*)lpDIBNew, (unsigned char*)lpDIB, sizeof(BITMAPINFOHEADER) + palSize + height * lineByte);
	unsigned char *lpDIBBitsNew = (unsigned char *)::FindDIBBits(lpDIBNew);
	int max = 0;
	int min = 255;
	int data;
	int  i, j;
	double pix[256];
	int sumpix = height * width;

	for (i = 0;i < 256;++i) {
		pix[i] = 0;
	}
	for (i = 0;i < height;i++) {
		for (j = 0;j < width;j++) {
			data = *(lpDIBBits + i * lineByte + j);
			pix[data]++;
		}
	}
	for (i = 0;i < 256;++i) {
		pix[i] = pix[i] / sumpix;
	}
	double SquErr[256];
	for (int i = 0;i < 256;++i) { //T=i 为阈值
		double w0 = 0, w1 = 0;
		double u0 = 0, u1 = 0;
		for (j = 0;j < i;++j) {
			w0 = w0 + pix[j];
			u0 =u0+ j * pix[j];
		}
		if(w0!=0)
			u0 = u0 / w0;
		w1 = 1 - w0;
		for (j = i;j < 256;++j) {
			u1 =u1 +j * pix[j];
		}
		if(w1!=0)
			u1 = u1 / w1;
		SquErr[i] = w0 * w1*(u1 - u0)*(u1 - u0);
		
	}
	int maxpos=0;
	double maxerr = SquErr[0];
	for (i = 0;i < 256;++i) { //求最大方差
		if (maxerr < SquErr[i]) {
			maxpos = i;
			maxerr = SquErr[i];
		}
	}
	for (i = 0;i < height;i++) {
		for (j = 0;j < width;j++) {
			if(*(lpDIBBits + i * lineByte + j)<maxpos)
				*(lpDIBBitsNew + i * lineByte + j) = 0;
			else
				*(lpDIBBitsNew + i * lineByte + j) = 255;
		}
	}
	::GlobalUnlock(dib);
	::GlobalUnlock(dibNew);

	CMainFrame* pFrame = (CMainFrame *)(AfxGetApp()->m_pMainWnd);
	pFrame->SendMessage(WM_COMMAND, ID_FILE_NEW);

	CDemoView* pView = (CDemoView*)pFrame->MDIGetActive()->GetActiveView();
	CDemoDoc* pDocNew = pView->GetDocument();

	pDocNew->ReplaceHDIB((HDIB)dibNew);
	pDocNew->InitDIBData();
	pDocNew->UpdateAllViews(pView);
	Invalidate();
}

还有图像压缩的一些东西,下次再写