1. 程式人生 > >基於opencv的影象縮放,旋轉,透視變換。

基於opencv的影象縮放,旋轉,透視變換。

工具程式碼:


#define WARPSTEPSIZE 0.2;
#define RESIZESTEPSIZE 0.1;
#define ROTATESTEPSIZE 10;

float g_H_value = 0;
float g_resize_value = 0;
float g_rotate_value = 0;

IplImage *dst_resize, *dst_rotate, *dst_perspective;
IplImage * img_7;
CvMat warp_matric;

IplImage * zoom(IplImage *img, float value) {
	IplImage * img_resize = cvCreateImage(
		CvSize(img->width*(1 + value), img->height*(1 + value)),
		img->depth,
		img->nChannels
	);
	cvResize(img, img_resize, CV_INTER_LINEAR);
	return img_resize;
}

void zoom_realize() {
	cvNamedWindow("zoom_realize");
	while (1) {
		cvShowImage("zoom_realize", dst_resize);
		char c = cvWaitKey(10);
		switch (c)
		{
		case 43:
			g_resize_value = RESIZESTEPSIZE;
			dst_resize=zoom(dst_resize, g_resize_value);
			break;
		case 45:
			g_resize_value = -RESIZESTEPSIZE;
			dst_resize=zoom(dst_resize, g_resize_value);
			break;
		case 27:
			break;
		}
		if (c == 27)
			break;
	}
	cvReleaseImage(&dst_resize);
	dst_resize = cvCloneImage(img_7);
	cvDestroyWindow("zoom_realize");
}

IplImage* rotate_degree(IplImage *img, float degree) {
	IplImage *img_retate = cvCreateImage(
		cvGetSize(img),
		img->depth,
		img->nChannels
	);
	cout << degree << endl;
		CvPoint2D32f center;
		center.x = (float)(img->width / 2 + 0.5);
		center.y = (float)(img->height / 2 + 0.5);
		float f[6];

		//計算二位旋轉仿射二位矩陣
		CvMat M = cvMat(2, 3, CV_32F, f);
		cv2DRotationMatrix(center, degree, 1, &M);
		cvWarpAffine(img, img_retate, &M, CV_INTER_LINEAR + CV_WARP_FILL_OUTLIERS, CvScalar(0));
		cout << degree<<endl;
		cvNamedWindow("re");
		cvShowImage("re", img_retate);
		cvWaitKey(0);
		cvDestroyWindow("re");
		return img_retate;
}

void rotate_realize() {
	cvNamedWindow("rotate_realize",0);
	while (1) {
		cvShowImage("rotate_realize", dst_rotate);
		char c = cvWaitKey(10);
		switch (c)
		{
		case 43:
			g_rotate_value += ROTATESTEPSIZE;
			cout << g_rotate_value<<endl;
			dst_rotate =rotate_degree (dst_rotate, g_rotate_value);
			break;
		case 45:
	        g_rotate_value -= ROTATESTEPSIZE;
			dst_rotate = rotate_degree(dst_rotate, g_rotate_value);
			break;
		case 27:
			break;
		}
		if (c == 27)
			break;
	}
	g_rotate_value = 0;
	cvReleaseImage(&dst_rotate);
	dst_rotate = cvCloneImage(img_7);
	cvDestroyWindow("rotate_realize");
}
//影象透視投影;
void change_H_plus(CvMat *H,char d,float g_H_value) {
	if (d == 49)cvSet2D(H, 0, 0, cvGetReal2D(H, 0, 0) + g_H_value);
	if (d == 50)cvSet2D(H, 0, 1, cvGetReal2D(H, 0, 1) + g_H_value);
	if (d == 51)cvSet2D(H, 0, 2, cvGetReal2D(H, 0, 2) + g_H_value);
	if (d == 52)cvSet2D(H, 1, 0, cvGetReal2D(H, 1, 0) + g_H_value);
	if (d == 53)cvSet2D(H, 1, 1, cvGetReal2D(H, 1, 1) + g_H_value);
	if (d == 54)cvSet2D(H, 1, 2, cvGetReal2D(H, 1, 2) + g_H_value);
	if (d == 55)cvSet2D(H, 2, 0, cvGetReal2D(H, 2, 0) + g_H_value);
	if (d == 56)cvSet2D(H, 2, 1, cvGetReal2D(H, 2, 1) + g_H_value);
	if (d == 57)cvSet2D(H, 2, 2, cvGetReal2D(H, 2, 2) + g_H_value);
}

IplImage * WarpPerspective_Plusorsub(IplImage * src, IplImage *dst, CvMat * H, char d, float g_H_value) {
	change_H_plus(H, d, g_H_value);
	IplImage *dst_Perspective = cvCreateImage(cvGetSize(src), src->depth, src->nChannels);
	cvWarpPerspective(src, dst_Perspective, H, CV_INTER_LINEAR + CV_WARP_FILL_OUTLIERS, cvScalarAll(0));
	/*
	cvReleaseImage(&dst);
	dst = cvCloneImage(dst_Perspective);
	*/
	return dst_Perspective;
}

void WarpPerspective(IplImage *src, IplImage *dst, CvMat warp_matric, char d) {
	CvMat *H = cvCloneMat(&warp_matric);
	cvNamedWindow("Warp", CV_WINDOW_AUTOSIZE);
	while (1) {
		cvShowImage("Warp", dst);
		char c = cvWaitKey(10);
		switch (c)
		{
		case 43:
			g_H_value= WARPSTEPSIZE;
			dst=WarpPerspective_Plusorsub(src, dst, H, d, g_H_value);
			break;
		case 45:
			g_H_value = -WARPSTEPSIZE;
			dst=WarpPerspective_Plusorsub(src, dst, H, d, g_H_value);
			break;
		case 27:
			break;
		}
		if (c == 27)
			break;
	}
	g_H_value = 0;
	cvDestroyWindow("Warp");
	cvReleaseImage(&dst);
	dst = cvCloneImage(src);
}

void perspective_realize() {
	cvNamedWindow("Perspective");
	while (1) {
		cvShowImage("Perspective",dst_perspective);
		char d = cvWaitKey(10);
		if (d == 27)
			break;
		else if (d >= 49 && d <= 57)
			WarpPerspective(img_7, dst_perspective, warp_matric, d);
     }
	cvDestroyWindow("Perspective");
}

實現程式碼:

void opencv_4_3::ans_7() {
    img_7 = cvLoadImage("..//..//dog.bmp");
	//初始化單位矩陣
    float f[9] = { 1,0,0,0,1,0,0,0,1 };
    warp_matric = cvMat(3, 3, CV_32FC1, f);

	
	dst_rotate = cvCloneImage(img_7);
	dst_resize = cvCloneImage(img_7);
	dst_perspective=cvCloneImage(img_7);
	
	cout << "fist z mean zoom,then + for zoom out,- for zoom in" << endl;
	cout << "first r mean rotate,then + for clockwise rotation,- for anticlockwise" << endl;
	cout << "first p mean perspective,then please input g_H_value  final + mean plus perspective,- for sub" << endl;
	cvNamedWindow("opencv_4_7", CV_WINDOW_AUTOSIZE);
	while (true)
	{
		cvShowImage("opencv_4_7", img_7);
		char c = cvWaitKey(15);
		switch (c)
		{
		case 27:
			break;
		case 122:
			zoom_realize();
			break;
		case 114:
			rotate_realize();
			break;
		case 112:
			perspective_realize();
			break;
		default:
			break;
		}
		if (c == 27)
			break;
	}
	cvReleaseImage(&img_7);
	cvReleaseImage(&dst_rotate);
	cvReleaseImage(&dst_resize);
	cvReleaseImage(&dst_perspective);
	cvDestroyWindow("opencv_4_7");
}

影象參考:

透視變換參考: