计算机图形学课设题目

计算机图形学 专栏收录该内容
2 篇文章 0 订阅

构造完整的DDA画线算法程序,并对各种情况进行测试。(20分)

#include <stdarg.h>
#include <windows.h>
#include <GL/glu.h>
#include <GL/gl.h>
#include <glut/glut.h>
#include<stdlib.h>  

//DDA算法——digital differentialanalyzer,数字微分析法 
void LineDDA(int x0, int y0, int xEnd, int yEnd)
{
    int dx = xEnd - x0;                             //x的增量
    int dy = yEnd - y0;                             //y的增量
    int steps;
    float xIncrement, yIncrement, x = x0, y = y0;
    if (abs(dx) > abs(dy))                          //谁的增量大
    {
        steps = abs(dx);
    }
    else
    {
        steps = abs(dy);
    }

    xIncrement = float(dx) / float(steps);          //x每步骤增量
    yIncrement = float(dy) / float(steps);          //y的每步增量

    glClear(GL_COLOR_BUFFER_BIT);
    //开始画点
    glBegin(GL_POINTS);
    glVertex3f(x0, y0, 0);                          //起点要画下
    for (int k = 0; k <= steps; ++k)
    {
        x += xIncrement;                            //x点+增量
        y += yIncrement;                            //y点+增量
        glVertex3f(x, y, 0);
    }
    glVertex3f(xEnd, yEnd, 0);                      //终点画下
    glEnd();
    glFlush();
}

//主循环方法
void display(void)
{
    glClear(GL_COLOR_BUFFER_BIT);
    glClearColor(25, 25 ,112, 0);
    glViewport(0, 0, 500, 500);
    LineDDA(30, 30, 200, 180);
}

//初始化方法
void myInit(void)
{
    glClearColor(1.0, 1.0, 1.0, 0.0);
    glColor3f(1.0, 0.0, 0.0);
    gluOrtho2D(0.0, 500.0, 0.0, 500.0);
    glMatrixMode(GL_MODELVIEW);
}

int main(int argc, char* argv[])
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowSize(300, 400);
    glutInitWindowPosition(200, 200);
    glutCreateWindow("Point");
    glutDisplayFunc(display);
    myInit();
    glutMainLoop();
    return(0);
}

编制完整的中点画线算法程序,并对各种情况进行测试。(20分)

#include <glut/glut.h>

void init()
{
    glEnable(GL_POINT_SMOOTH);
    glEnable(GL_LINE_SMOOTH);
    glEnable(GL_POLYGON_SMOOTH);
}

void Mid_Line1(int x1, int y1, int x2, int y2)
{
    int a, b, c, x, y, p, _2a, _2a_2b;
    if (x2 < x1)
    {
        int temp;
        temp = x1, x1 = x2, x2 = temp;
        temp = y1, y1 = y2, y2 = temp;
    }
    a = y1 - y2, b = x2 - x1;
    _2a = 2 * a, _2a_2b = _2a + 2 * b;
    y = y1, p = 2 * a + b;
    for (x = x1; x <= x2; ++x)
    {
        glVertex2i(x, y); //2表示二维坐标,i表示32位浮点数
        if (p > 0)
            p = p + _2a;
        else
            ++y, p += _2a_2b;
    }
}

void reshape(int w, int h)  //窗口绘画
{
    glViewport(0, 0, w, h);
    glLoadIdentity();
    gluOrtho2D(19, 31, 9, 21);
}
void display()  
{
    glClearColor(1, 1, 1, 0);
    glClear(GL_COLOR_BUFFER_BIT);
    glLineWidth(3);
    glColor3f(0.3, 0., 1); //点
    glBegin(GL_LINES);
    glVertex2i(20, 5), glVertex2i(30, 18); //线的起始点
    glEnd();
    glPointSize(8);
    glColor3f(1.0, 0.0, 1.0);
    glBegin(GL_POINTS);
    Mid_Line1(20, 5, 30, 18); //线
    glEnd();
    glFlush();
}

int main(int argc, char* argv[])
{
    glutInit(&argc, argv);  //初始化 GLUT 库
    glutInitWindowSize(400, 400);
    glutCreateWindow("中点画线算法演示!");
    glutReshapeFunc(reshape); 
    display();
    glutDisplayFunc(display); // 注册场景绘制函数
    glutMainLoop();
}

分别绘制2个正方形区域,左边正方形使用实模式绘制,右边正方形选用一个自己喜欢的图案填充。(20分)

// MultiObject.c
#include <glut/glut.h>
void Viewport(int x, int y, int w, int h)
{
	glViewport(x, y, w, h); // 定义视口
	glLoadIdentity(); // 消除其他视口的影响, 函数介绍见后续章节
}
void Paint()
{
	int w = glutGet(GLUT_WINDOW_WIDTH) / 2; // 计算视区宽度
	int h = glutGet(GLUT_WINDOW_HEIGHT); // 计算视区高度
	GLubyte fly[]{
	0X00,0X01,0X80,0X00,0X00,0X02,0X40,0X00,
	0X00,0X04,0X20,0X00,0X00,0X08,0X20,0X00,
	0X00,0X10,0X10,0X00,0X00,0X20,0X08,0X00,
	0X00,0X40,0X04,0X00,0X00,0X80,0X02,0X00,
	0X01,0X00,0X01,0X00,0X02,0X00,0X00,0X80,
	0X04,0X00,0X00,0X40,0X08,0X00,0X00,0X20,
	0X08,0X00,0X00,0X20,0X20,0X00,0X00,0X08,
	0X20,0X00,0X00,0X04,0X40,0X00,0X00,0X02,
	0X80,0X00,0X00,0X01,0X40,0X00,0X00,0X02,
	0X20,0X00,0X00,0X04,0X10,0X00,0X00,0X08,
	0X08,0X00,0X00,0X10,0X04,0X00,0X00,0X20,
	0X02,0X00,0X00,0X40,0X01,0X00,0X00,0X80,
	0X00,0X80,0X01,0X00,0X00,0X40,0X02,0X00,
	0X00,0X20,0X04,0X00,0X00,0X10,0X08,0X00,
	0X00,0X08,0X10,0X00,0X00,0X04,0X20,0X00,
	0X20,0X02,0X40,0X00,0X00,0X01,0X80,0X00
	};

	glClearColor(0.2, 0.3, 0.4, 1); // 窗口整体背景颜色

	glClear(GL_COLOR_BUFFER_BIT); // 清除颜色缓存

	Viewport(0, 0, w, h); // 左下方视口

	glColor3f(1, 0.8, 0.6); // 设置当前颜色, 茶色

	glRectf(-0.8, -0.4, 0.8, 0.4); // 定义正方形

	Viewport(w, 0, w, h); // 右下方视口

	glEnable(GL_POLYGON_STIPPLE); //启动点化多边形,

	glPolygonStipple(fly);	//设置多边形点化图案,这个是自定义的

	glColor3f(1, 0.8, 0.6); // 设置当前颜色, 茶色
	
	glRectf(-0.8, -0.4, 0.8, 0.4); // 定义正方形
	glDisable(GL_POLYGON_STIPPLE); //关闭点化多边形

	glFlush(); // 强制OpenGL命令序列在有限的时间内完成执行
}
int main(int argc, char* argv[])
{
	glutInit(&argc, argv); // 初始化GLUT, 记录main()函数的参数
	glutCreateWindow("四个预定义几何形体"); // 指定窗口标题
	glutDisplayFunc(Paint); // 指定场景绘制函数
	glutMainLoop(); // 开始执行
}

在默认的坐标值范围内任意指定线段的两个端点坐标和裁剪窗口,请使用Cohen-Sutherland算法构造一个完成该裁剪任务的完整程序,并对各种情况进行测试。(25分)

#include <Windows.h>
#include <glut/glut.h>
//
//区域码
const GLint leftBitCode = 0x1;
const GLint rightBitCode = 0x2;
const GLint buttonBitCode = 0x4;
const GLint topBitCode = 0x8;
GLint winWidth = 640, winHeight = 480;
class screenPT
{
public:
	GLfloat x, y;
};
inline GLint inside(GLint code) { return GLint(!code); }	//判断点是否在裁剪区内
inline GLint reject(GLint code1, GLint code2) { return GLint(code1 & code2); }	//判断能否完全排除一条线段
inline GLint accept(GLint code1, GLint code2) { return GLint(!(code1 | code2)); }	//判断能否完全接受一条线段
inline void swapPT(screenPT& a, screenPT& b) { screenPT t = a; a = b; b = t; }	//交换两个点
inline void swapCode(GLubyte& a, GLubyte& b) { GLubyte t = a; a = b; b = t; }	//交换两个区域码
//确定一个点所在位置的区域码
GLubyte encode(const screenPT& p, const screenPT& winMin, const screenPT& winMax)
{
	GLubyte code = 0x00;
	if (p.x < winMin.x)
		code |= leftBitCode;
	if (p.x > winMax.x)
		code |= rightBitCode;
	if (p.y < winMin.y)
		code |= buttonBitCode;
	if (p.y > winMax.y)
		code |= topBitCode;
	return code;
}
//在屏幕上画一条未裁剪的线,由裁剪函数调用
void drawOneLine(const screenPT& a, const screenPT& b)
{
	glBegin(GL_LINES);
	glVertex2f(a.x, a.y);
	glVertex2f(b.x, b.y);
	glEnd();
}
//裁剪函数
void lineClip(screenPT winMin, screenPT winMax, screenPT lineBegin, screenPT lineEnd)
{
	GLubyte code1, code2;	//保存两个端点的区域码
	GLboolean done = false, plotLine = false;	//判断裁剪是否结束和是否要绘制直线
	GLfloat k;				//斜率
	while (!done)
	{
		code1 = encode(lineBegin, winMin, winMax);
		code2 = encode(lineEnd, winMin, winMax);
		if (accept(code1, code2))			//当前直线能完全绘制
		{
			done = true;
			plotLine = true;
		}
		else
		{
			if (reject(code1, code2))		//当前直线能完全排除
				done = true;
			else
			{
				if (inside(code1))	//若lineBegin端点在裁剪区内则交换两个端点使它在裁剪区外
				{
					swapPT(lineBegin, lineEnd);
					swapCode(code1, code2);
				}
				//计算斜率
				if (lineBegin.x != lineEnd.x)
					k = (lineEnd.y - lineBegin.y) / (lineEnd.x - lineBegin.x);
				//开始裁剪,以下与运算若结果为真,
				//则lineBegin在边界外,此时将lineBegin移向直线与该边界的交点
				if (code1 & leftBitCode)
				{
					lineBegin.y += (winMin.x - lineBegin.x) * k;
					lineBegin.x = winMin.x;
				}
				else if (code1 & rightBitCode)
				{
					lineBegin.y += (winMax.x - lineBegin.x) * k;
					lineBegin.x = winMax.x;
				}
				else if (code1 & buttonBitCode)
				{
					if (lineBegin.x != lineEnd.x)
						lineBegin.x += (winMin.y - lineBegin.y) / k;
					lineBegin.y = winMin.y;
				}
				else if (code1 & topBitCode)
				{
					if (lineBegin.x != lineEnd.x)
						lineBegin.x += (winMax.y - lineBegin.y) / k;
					lineBegin.y = winMax.y;
				}
			}
		}
	}
	if (plotLine)
		drawOneLine(lineBegin, lineEnd);	//绘制裁剪好的直线
}
//
void rect(screenPT winMin, screenPT winMax)
{
	glBegin(GL_LINE_LOOP);
	glVertex2f(winMin.x, winMin.y);
	glVertex2f(winMax.x, winMin.y);
	glVertex2f(winMax.x, winMax.y);
	glVertex2f(winMin.x, winMax.y);
	glEnd();
}
void init()
{
	glViewport(0, 0, winWidth, winHeight);
	glClearColor(1.0, 1.0, 1.0, 0.0);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluOrtho2D(0, winWidth, 0, winHeight);
	glMatrixMode(GL_MODELVIEW);
}
void display()
{
	screenPT winMin, winMax, lineBegin, lineEnd;
	winMin.x = 100.0;	winMin.y = 50.0;
	winMax.x = 400.0;	winMax.y = 300.0;
	lineBegin.x = 0.0;	lineBegin.y = 0.0;
	lineEnd.x = winWidth;	lineEnd.y = winHeight;
	glClear(GL_COLOR_BUFFER_BIT);
	glColor3f(0.0, 0.0, 0.0);
	rect(winMin, winMax);	//为裁剪区域绘制一个边框
	lineClip(winMin, winMax, lineBegin, lineEnd);
	lineBegin.y = 240.0;	lineEnd.y = 240.0;
	lineClip(winMin, winMax, lineBegin, lineEnd);
	lineBegin.x = 320.0;	lineBegin.y = 0.0;
	lineEnd.x = 320.0;	lineEnd.y = winHeight;
	lineClip(winMin, winMax, lineBegin, lineEnd);
	glFlush();
}
int main(int argc, char** argv)
{
	glutInit(&argc, argv);
	glutInitWindowPosition(100, 100);
	glutInitWindowSize(winWidth, winHeight);
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
	glutCreateWindow("线段");
	init();
	glutDisplayFunc(display);
	glutMainLoop();
	return 0;
}

编写一个程序,显示如图所示的两个相交长方体。要求自己构造透视变换函数,不能调用图形软件包提供的透视变换函数。其中,较近的长方体用红色显示,较远的长方体用蓝色显示。(50分)

#include<glut/glut.h>
void xtglFrustum(double L, double R, double B, double T, double N, double F, double a, double b)
{
	double s[] = {
		2 / (R - L),0,0,-(R + L) / (R - L),
		0,2 / (T - B),0,-(T + B) / (T - B),
		0,0,(-2) / (F - N),-(F + N) / (F - N),
		0,0,0,1
	};

	glMultMatrixd(s);

	double z0 = -N;

	double d[] = {
		1,0,0,0,
		0,1,0,0,
		-a,-b,1,0,
		a * z0,b * z0,0,1
	};

	glMultMatrixd(d);

}

void Paint() {
	glClearColor(0.2, 0.3, 0.4, 1); // 窗口整体背景颜色

	glClear(GL_COLOR_BUFFER_BIT); // 清除颜色缓存

	glLoadIdentity();//重置当前指定的矩阵为单位矩阵

	xtglFrustum(-2, 2, -3, 3, -2, 2, -0.25, -0.25);

	glBegin(GL_QUADS);
	{
		//蓝色
		//后面
		glColor3f(0, 0, 0.7);
		glVertex3f(-1, 0, 0);
		glVertex3f(-1, 2, 0);
		glVertex3f(1, 2, 0);
		glVertex3f(1, 0, 0);
		//顶部
		glColor3f(0, 0, 0.4);
		glVertex3f(1, 2, 0);
		glVertex3f(-1, 2, 0);
		glVertex3f(-1, 2, -1);
		glVertex3f(1, 2, -1);
		//前面
		glColor3f(0, 0, 1);
		glVertex3f(-1, 2, -1);
		glVertex3f(1, 2, -1);
		glVertex3f(1, 0, -1);
		glVertex3f(-1, 0, -1);
		//底部
		glColor3f(0, 0, 1);
		glVertex3f(1, 0, 0);
		glVertex3f(-1, 0, 0);
		glVertex3f(-1, 0, -1);
		glVertex3f(1, 0, -1);
		//左边
		glColor3f(0, 0, 1);
		glVertex3f(-1, 0, 0);
		glVertex3f(-1, 2, 0);
		glVertex3f(-1, 2, -1);
		glVertex3f(-1, 0, -1);
		//右边
		glColor3f(0, 0, 0.7);
		glVertex3f(1, 2, -1);
		glVertex3f(1, 0, -1);
		glVertex3f(1, 0, 0);
		glVertex3f(1, 2, 0);

		//红色
		glColor3f(0.7, 0, 0);
		//后边
		glVertex3f(-0.5, 0, -1.5);
		glVertex3f(-0.5, 1, -1.5);
		glVertex3f(0.5, 1, -1.5);
		glVertex3f(0.5, 0, -1.5);
		//顶部
		glColor3f(0.3, 0, 0);
		glVertex3f(-0.5, 1, -1.5);
		glVertex3f(0.5, 1, -1.5);
		glVertex3f(0.5, 1, -2);
		glVertex3f(-0.5, 1, -2);
		//前面
		glColor3f(1, 0, 0);
		glVertex3f(-0.5, 1, -2);
		glVertex3f(0.5, 1, -2);
		glVertex3f(0.5, 0, -2);
		glVertex3f(-0.5, 0, -2);
		//底部
		glColor3f(1, 0, 0);
		glVertex3f(0.5, 0, -1.5);
		glVertex3f(-0.5, 0, -1.5);
		glVertex3f(-0.5, 0, -2);
		glVertex3f(0.5, 0, -2);
		//左边
		glColor3f(1, 0, 0);
		glVertex3f(-0.5, 0, -1.5);
		glVertex3f(-0.5, 1, -1.5);
		glVertex3f(-0.5, 1, -2);
		glVertex3f(-0.5, 0, -2);
		//右边
		glColor3f(0.7, 0, 0);
		glVertex3f(0.5, 1, -2);
		glVertex3f(0.5, 0, -2);
		glVertex3f(0.5, 0, -1.5);
		glVertex3f(0.5, 1, -1.5);
	}
	glEnd();
	glFlush();
}

int main(int argc, char* argv[])
{
	glutInit(&argc, argv);
	glutInitWindowSize(500, 500);
	glutCreateWindow("透视投影");
	glutDisplayFunc(Paint);
	glutMainLoop();
}

演示一个不断旋转、缩放和移动的正三棱锥。要求正三棱锥4个面的颜色各不相同。可以分成三个小题完成。

#include<windows.h>
#include<glut/glut.h>
#include<stdlib.h>
#include<stdio.h>
#include<math.h>

float pi = 3.1415926;
float time;
//设置一组变化的周期
void Timer(int millis)
{
	float dtime = 50;// 延迟时间
	time = fmod(time + dtime, 360);
	glutPostRedisplay(); //标记当前窗口重新绘制
	glutTimerFunc(millis, Timer, millis);  // 改变和位置有关的变量,然后调用glutPostRedisplay(); 用来重绘
}


//设置三角形的初始位置
void Reshape(int w, int h)
{
	glViewport(0, 0, w, h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();   //重置当前指定的矩阵为单位矩阵
	gluPerspective(30, (float)w / h, 1, 1000);
	glTranslatef(0, 0, -8);
	glRotatef(30, 1, 0, 0);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}
//s三角形的四个面
void triangle(float r)
{
	glPushMatrix();
	glColor3f(0.5, 1, 0);
	glTranslatef(0, 0, r * sin(pi / 3) / 3);  //转换
	glRotatef(-19.47, 1, 0, 0);
	glBegin(GL_TRIANGLES);
	{
		glVertex2f(-r / 2, 0);
		glVertex2f(r / 2, 0);
		glVertex2f(0, r * sin(pi / 3));
	}
	glEnd();
	glPopMatrix(); //从栈中取回原先的状态


	glPushMatrix(); //继续压入当前状态=======第一次
	glColor3f(0, 0.5, 1);
	glRotatef(120, 0, 1, 0);
	glTranslatef(0, 0, r * sin(pi / 3) / 3);
	glRotatef(-19.47, 1, 0, 0);
	glBegin(GL_TRIANGLES);
	{
		glVertex2f(-r / 2, 0);
		glVertex2f(r / 2, 0);
		glVertex2f(0, r * sin(pi / 3));
	}
	glEnd();
	glPopMatrix();


	glPushMatrix();//继续压入当前状态=======第二次
	glColor3f(0, 1, 0.2);
	glRotatef(240, 0, 1, 0);
	glTranslatef(0, 0, r * sin(pi / 3) / 3);
	glRotatef(-19.47, 1, 0, 0);
	glBegin(GL_TRIANGLES);
	{
		glVertex2f(-r / 2, 0);
		glVertex2f(r / 2, 0);
		glVertex2f(0, r * sin(pi / 3));
	}
	glEnd();
	glPopMatrix();

	glPushMatrix();//继续压入当前状态=======第三次
	glColor3f(0.6, 0.1, 0.4);
	glTranslatef(0, 0, r * sin(pi / 3) / 3);
	glRotatef(-90, 1, 0, 0);
	glBegin(GL_TRIANGLES);
	{
		glVertex2f(-r / 2, 0);
		glVertex2f(r / 2, 0);
		glVertex2f(0, r * sin(pi / 3));
	}
	glEnd();
	glPopMatrix();
}
void Paint()
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glLoadIdentity();
	glRotatef(time, 0, 1, 0);
	glRotatef(-65, 50, 30, 0);
	glScalef(fabs((time - 180) / 180), fabs((time - 180) / 180), fabs((time - 180) / 180));
	triangle(2);
	glutSwapBuffers();
}
int main(int argc, char* argv[])
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
	glutInitWindowPosition(50, 50);
	glutInitWindowSize(500, 500);
	glutCreateWindow("正三棱锥");
	glutReshapeFunc(Reshape);
	glutTimerFunc(25, Timer, 25);
	glutDisplayFunc(Paint);
	glEnable(GL_DEPTH_TEST);
	glutMainLoop();
	return 0;
}

使用OpenCV装入一幅彩色图像,并显示该图像。然后在源图像窗口中使用鼠标选取一个矩形区域(可通过两次按下鼠标左键选取矩形的两个对角顶点来实现),并在结果图像窗口中显示源图像中被选取的部分

#include <iostream>
#include <stdio.h>
#include<opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/opencv.hpp>
#include <stdio.h>
using namespace cv;
IplImage* src = 0;
IplImage* tmp = 0;
IplImage* tmp1 = 0;
IplImage* org = 0;
void on_mouse(int event, int x, int y, int flags, void* ustc)
{
	static CvPoint pre_pt = { -1,-1 };
	static CvPoint cur_pt = { -1,-1 };
	CvFont font;
	cvInitFont(&font, CV_FONT_HERSHEY_SIMPLEX, 0.5, 0.5, 0, 1, CV_AA);//初始化字体
	char temp[16];

	if ((event == CV_EVENT_LBUTTONDOWN) && (flags))//鼠标左键按下时
	{
		sprintf_s(temp, "(%d,%d)", x, y);//格式化字符串
		pre_pt = cvPoint(x, y);//获取当前点坐标值
		cvPutText(src, temp, pre_pt, &font, cvScalar(0, 0, 0, 255));//在图像是打印字符
		cvCircle(src, pre_pt, 2, cvScalar(255, 0, 0, 0), CV_FILLED, CV_AA, 0);//在图像上画圆
		cvShowImage("src", src);
		//cvCopy(src,tmp);//这句有没有,就是单目标和多目标的问题
	}
	else if ((event == CV_EVENT_MOUSEMOVE) && (flags & CV_EVENT_LBUTTONDOWN))
	{//鼠标移动并且鼠标左键按下
		sprintf_s(temp, "(%d,%d)", x, y);//格式化字符串
		cur_pt = cvPoint(x, y);//获取当前点坐标值		
		cvPutText(src, temp, cur_pt, &font, cvScalar(0, 0, 0, 255));//在图像是打印字符
		cvRectangle(src, pre_pt, cur_pt, cvScalar(0, 255, 0, 0), 2, 8, 0);//在图像上画矩形
		cvShowImage("src", src);
		cvCopy(tmp, src);//将img复制到临时图像tmp上,用于实时显示
	}
	else if (event == CV_EVENT_LBUTTONUP)
	{//鼠标左键弹起
		sprintf_s(temp, "(%d,%d)", x, y);//字体格式化
		cur_pt = cvPoint(x, y);//获取当前点坐标值		
		cvPutText(src, temp, cur_pt, &font, cvScalar(0, 0, 0, 255));//在图像是打印字符
		cvCircle(src, cur_pt, 2, cvScalar(255, 0, 0, 0), CV_FILLED, CV_AA, 0);//在图像上画圆
		cvRectangle(src, pre_pt, cur_pt, cvScalar(0, 255, 0, 0), 2, 8, 0);//在图像上画矩形
		cvShowImage("src", src);

		/******************************************************************/
		int width = abs(pre_pt.x - cur_pt.x); //两点横坐标差 
		int height = abs(pre_pt.y - cur_pt.y); //两点纵坐标差 
		if (width == 0 || height == 0)
		{  //两者中有一个为零时销毁窗口
			cvDestroyWindow("dst");
			return;
		}
		tmp1 = cvCreateImage(cvSize(width, height), org->depth, org->nChannels);
		CvRect rect;
		if (pre_pt.x < cur_pt.x && pre_pt.y < cur_pt.y)
		{
			rect = cvRect(pre_pt.x, pre_pt.y, width, height);
		}
		else if (pre_pt.x > cur_pt.x && pre_pt.y < cur_pt.y)
		{
			rect = cvRect(cur_pt.x, pre_pt.y, width, height);
		}
		else if (pre_pt.x > cur_pt.x && pre_pt.y > cur_pt.y)
		{
			rect = cvRect(cur_pt.x, cur_pt.y, width, height);
		}
		else if (pre_pt.x<cur_pt.x && pre_pt.y>cur_pt.y)
		{
			rect = cvRect(pre_pt.x, cur_pt.y, width, height);
		}
		cvSetImageROI(org, rect);//设置图像的感兴趣区域  
		cvCopy(org, tmp1); //将感兴趣区域复制到tmp1 
		cvResetImageROI(org);//释放图像的感兴趣区域  
		cvDestroyWindow("dst");//销毁上次的显示图像  
		cvNamedWindow("dst", 1);//新建窗口  
		cvShowImage("dst", tmp1); //显示感兴趣的图像 
		Mat mat = cvarrToMat(tmp1);
		imwrite("D://dst.jpg", mat); //保存感兴趣图像 
/******************************************************************/
	}
}
int main()
{
	src = cvLoadImage("lena.jpg", 1);//读入图像
	tmp = cvCloneImage(src);//复制图像到临时图像上 
	org = cvCloneImage(src);//保存原始图像 
	cvNamedWindow("src", 1);//新建窗口
	cvSetMouseCallback("src", on_mouse, 0);//注册鼠标响应回调函数

	cvShowImage("src", src);//显示图像
	cvWaitKey(0);//等待按键按下 
	cvDestroyAllWindows();//销毁所有窗口
	cvReleaseImage(&src);//释放图像
	cvReleaseImage(&tmp);//释放图像
	return 0;
}

使用OpenCV编制一个简单的徒手绘图程序。该程序使用鼠标绘制图形,当鼠标左键按下时开始绘制一条曲线,鼠标左键松开时停止当前曲线的绘制。按下“S”键将当前绘制结果存入图像文件,按下“C”清除所有绘制结果。要求使用白色背景,黑色曲线。可拓展考虑绘制封闭曲线和填充区域。

#include <iostream>
#include <opencv2/cvconfig.h> 
#include<opencv2/opencv.hpp>
#include<opencv2/highgui/highgui.hpp>
using namespace std;
using namespace cv;
#pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"")  
const char* pstrWindowsMouseDrawTitle = "鼠标绘图";
// 鼠标消息的回调函数  
void on_mouse(int event, int x, int y, int flags, void* param)
{
    static bool s_bMouseLButtonDown = false;
    static CvPoint s_cvPrePoint = cvPoint(0, 0);

    switch (event)
    {
    case CV_EVENT_LBUTTONDOWN:
        s_bMouseLButtonDown = true;
        s_cvPrePoint = cvPoint(x, y);
        break;

    case  CV_EVENT_LBUTTONUP:
        s_bMouseLButtonDown = false;
        break;

    case CV_EVENT_MOUSEMOVE:
        if (s_bMouseLButtonDown)
        {
            CvPoint cvCurrPoint = cvPoint(x, y);
            cvLine((IplImage*)param, s_cvPrePoint, cvCurrPoint, CV_RGB(0, 0, 20), 3);
            s_cvPrePoint = cvCurrPoint;
            cvShowImage(pstrWindowsMouseDrawTitle, (IplImage*)param);
        }
        break;
    }
}
int main()
{
    const int MAX_WIDTH = 500, MAX_HEIGHT = 400;
    const char* pstrSaveImageName = "1.jpg";

    IplImage* pSrcImage = cvCreateImage(cvSize(MAX_WIDTH, MAX_HEIGHT), IPL_DEPTH_8U, 3);
    cvSet(pSrcImage, CV_RGB(255, 255, 255)); //可以用cvSet()将图像填充成白色  
    cvNamedWindow(pstrWindowsMouseDrawTitle, CV_WINDOW_AUTOSIZE);
    cvShowImage(pstrWindowsMouseDrawTitle, pSrcImage);

    cvSetMouseCallback(pstrWindowsMouseDrawTitle, on_mouse, (void*)pSrcImage);

    int c;
    do {
        c = cvWaitKey(0);
        switch ((char)c)
        {
        case 'c':
            cvSet(pSrcImage, CV_RGB(255, 255, 255));
            cvShowImage(pstrWindowsMouseDrawTitle, pSrcImage);
            break;

        case 's':
            Mat mat = cvarrToMat(pSrcImage);
            imwrite(pstrSaveImageName, mat);
            break;
        }
    } while (c > 0 && c != 27);

    cvDestroyWindow(pstrWindowsMouseDrawTitle);
    cvReleaseImage(&pSrcImage);
    return 0;
}

使用OpenCV编写一个演示傅立叶变换和逆变换的程序。该程序首先装入一幅灰度图像,并创建一个滑块(初始值为0,最大值为16),然后对该图像进行傅立叶正变换,在正变换的结果中将小于value(value = 滑块位置 * 250 - 2500)的元素改为value,最后对得到的结果进行傅立叶逆变换,并显示得到的结果图像

#include<opencv2/opencv.hpp>
#include<iostream>
using namespace std;
using namespace cv;

Mat src, src2;
Mat1f X, Y;
int value;
void on_change(int pos, void* prompt)
{
    X.copyTo(Y);
    Y.convertTo(Y, CV_32F, 1.0 / 255.0);  //float要在0-1之间才能显示 
   // src.copyTo(src3);
   // Y = src3; // 源图像转换为浮点数图像
    cout << (char*)prompt <<
        getTrackbarPos("TestBar", "源图像") << endl;
    dct(Y, Y); // DFT正变换
    //value = pos;
    value = 250 - pos * 25;
    cout << value << endl;
    Y = max(value, Y);
    idct(Y, Y); // 逆DCT
    //normalize(X, X, 1, 0, NORM_INF); // 增强对比度
    imshow("结果图", Y); // 显示图像
}
int main()
{
    src = imread("D://tuc//Cartoon_pictures//huli.jpg", 0); // 载入灰度图像
    if (src.empty()) return -1; // 载入图像失败
    imshow("源图像", src);
    src.copyTo(src2);
    X = src2;
    // imshow("结果图"); // 显示图像
    int pos = 0, m = 16; // 滑块位置,滑块位置最大值
    char prompt[] = "滑块位置:";
    createTrackbar("TestBar", "源图像", &pos, m, on_change, prompt);

    waitKey(); // 等待按键
}


  • 0
    点赞
  • 0
    评论
  • 2
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值