OpenCV学习——图像处理基础(一)

图像处理涉及的方面十分广泛,具体的方法种类也比较多,传统图像处理技术主要集中在图像的获取 、变换、增强、回复、压缩、分割、边缘检测等方面。随着新工具,新技术的不断出现,这些图像处理方法也在不断更新与发展。接下来讲解一些基础的图像操作。
一:对图像像素点进行操作
对图像像素点进行操作就是对灰度值进行操作,实际实现时先获得目标图像的灰度值,然后再对 灰度值进行数学操作,即可实现,具体代码如下:

#include 
#include 
using namespace cv;
using namespace std;

int main()
{
	Mat src = imread("F:/dog.jpg");
	namedWindow("input", CV_WINDOW_AUTOSIZE);//创建窗口 可以不用创建
	imshow("input", src);//显示原图像

	Mat gray_src;//定义一个新的图像
	cvtColor(src, gray_src, CV_BGR2GRAY);//将原图像转换成灰度图像
	namedWindow("output", CV_WINDOW_AUTOSIZE);//创建窗口
	imshow("output", gray_src);//显示灰度图像

	Mat g = gray_src.clone();//克隆新图,将灰度图像cope过来
	int height = gray_src.rows;//获取图像的高度
	int width = gray_src.cols;//获取图像的宽度
	for (int row = 0; row < height; row++)//for循环语句
	{
		for (int clo = 0; clo < width; clo++)
		{
			int gray = gray_src.at(row, clo);//获取图像的像素值
			g.at(row, clo) = 255 - gray;//对图像的像素值进行数值操作
		}
	}
	imshow("【翻转图】", g);

	Mat dst;
	dst.create(src.size(), src.type());//定义一个新的图像类,尺寸与类型类似于cope
	int heights = src.rows;
	int widths = src.cols;
	int nc = src.channels();//获取通道数,这里是一个三通道图像
	for (int row = 0; row < heights; row++)
	{
		for (int col = 0; col < widths; col++)
		{
			int b = src.at(row, col)[0];//获取原图像的b通道像素值
			int g = src.at(row, col)[1];//获取原图像的g通道像素值
			int r = src.at(row, col)[2];//获取原图像的r通道像素值
			dst.at(row, col)[0] = 255 - b;//对图像像素值进行数值操作
			dst.at(row, col)[1] = 255 - g;
			dst.at(row, col)[2] = 255 - r;
		}
		imshow("【多通道】", dst);
	}
	waitKey(0);
	return 0;
}

二:调整图像的亮度和对比度
有时候我们在对图像进行操作时也会用到调整对比度和亮度等,同样需要对图像的灰度值进行操作,具体代码如下:

#include 
#include 
using namespace cv;

int main()
{
	Mat src, dst;
	src = imread("F:/girl.png");//读入一副图像
	char input_win[] = "input image";//创建一个显示框
	namedWindow(input_win, CV_WINDOW_NORMAL);
	cvResizeWindow(input_win, 500, 500);//设置显示窗口大小
	imshow(input_win, src);

	int height = src.rows;//获取图像的参数,高度,宽度,通道数
	int width = src.cols;
	int n = src.channels();
	dst = Mat::zeros(src.size(), src.type());//创建一个和原图像大小 类型相同的空白图像
	float alpha = 1.0;//设置阿尔法值
	float bata = 50;//设置贝塔值

	for (int row = 0; row < height; row++)
	{
		for (int col = 0; col < width; col++)
		{
			if (n == 1)//单通道的调整对比度亮度
			{
				float a = src.at(row, col);
				dst.at(row, col) = saturate_cast(a*alpha + bata);//公式
			}
			else if (n == 3)//3通道的对比度亮度调整
			{
				float b = src.at(row, col)[0];//bule
				float g = src.at(row, col)[1];//green
				float r = src.at(row, col)[2];//rad
				dst.at(row, col)[0] = saturate_cast(b*alpha + bata);
				dst.at(row, col)[1] = saturate_cast(g*alpha + bata);
				dst.at(row, col)[2] = saturate_cast(r*alpha + bata);
			}
		}
	}
	char output_title[] = "this is a gril";//显示窗口抬头设置
	namedWindow(output_title, CV_WINDOW_NORMAL);
	cvResizeWindow(output_title, 500, 500);//设置显示窗口大小
	imshow(output_title, dst);//显示出处理过后的图像
	waitKey(0);
	return 0;
}

三:绘制图形与文字
在实际的图像处理中,有时候需要我们在目标图像上绘制一些图形或者是写一些文字,例如在捕捉人脸时,需要绘制一个圆进行捕捉,下面代码即可实现在图像上绘制图形以及文字:

#include 
#include 
#include 
#include 
using namespace cv;

Mat mygirl;//定义全局变量
void mylines();//声明函数
void myRectangle();//声明一个无返回值的矩形函数
void myellipse();//声明一个无返回值的椭圆函数
void mycircle();//声明一个无返回值的圆函数

int main()
{
	mygirl = imread("F:/openCV/girl.png");
	mylines();//调用直线函数
	myRectangle();//调用矩形函数
	myellipse();//调用椭圆函数
	mycircle();//调用圆函数

	putText(mygirl, "Hello openCV", Point(100, 100), CV_FONT_BLACK, 2.0, Scalar(12, 23, 200), 3, LINE_8);//CV_FONNT为字体类型,后面2.0为字体大小,3为字体粗细,8为line_8
	namedWindow("optput", CV_WINDOW_AUTOSIZE);//定义显示窗口
	imshow("optput", mygirl);//显示输出图像
	waitKey(0);
	return 0;
}

void mylines()//定义函数
{
	Point p1 = Point(200, 200);//第一个点的坐标
	Point p2;//另外一种表示方法
	p2.x = 400;
	p2.y = 400;
	Scalar color = Scalar(0, 0, 255);//直线的颜色定义 也可用Scalar(0,0,255)直接表示
	line(mygirl, p1, p2, color, 1, LINE_AA);
	//将直线画到图像上面 1是指线的粗细
	//int thickness = 1;
	//int linetype = 8;等于LINE_8,LINE_AA的意思是无锯齿直线
	//可以替换成line(mygirl,p1,p2,color,thickness,linetype);
}

void myRectangle()//定于矩形函数
{
	Rect rect = Rect(200, 250, 200, 250);//矩形的四个边
	Scalar color = Scalar(255, 0, 0);
	rectangle(mygirl, rect, color, 2, LINE_8);
}

void myellipse()//定义椭圆函数
{
	Scalar color = (0, 255, 0);//设置颜色
	ellipse(mygirl, Point(mygirl.rows / 2, mygirl.cols / 2), Size(mygirl.rows / 2, mygirl.cols / 2),90,0,360,2,LINE_AA);
	//Point为椭圆的原点位置:可以写成Point center = Point(mygirl.row/2,mygirl.col/2);
	//size为椭圆的尺寸大小
	//90为偏移的角度 偏移了90度
	//0到360是扩展的弧度 ,180是个半椭圆 360是一个封闭的椭圆;
}

void mycircle()//定义一个圆函数
{
	Scalar color = Scalar(0, 255, 255);
	Point center = Point(mygirl.rows / 2, mygirl.cols / 2);
	circle(mygirl, center, 150, color, 2, LINE_8);
	//150是半径,可以是数字 ,也可以用上面表示圆的原点方法表示
	//当thickness = -1时为实习圆,当为负数时为实心。
}

void myPolygon()
{
	Point pts[1][5];
	pts[0][0] = Point(100, 100);
	pts[0][1] = Point(100, 200);
	pts[0][2] = Point(200, 200);
	pts[0][3] = Point(200, 100);
	pts[0][4] = Point(100, 100);

	const Point* ptts[] = { pts[0] };
	int npt[] = { 5 };
	Scalar color = Scalar(255, 12, 255);
	fillPoly(mygirl, ppts,npt, 1, color, 8);
}

四:生成随机线
图像图例中,产生随机数是一个常用的手段,代码如下:

#include 
#include 
using namespace cv;

void RandomLineDemo();//声明随机函数

int main()
{
	RandomLineDemo();//调用随机函数
	waitKey(0);
	return 0;
}

void RandomLineDemo()//定义随机函数
{
	RNG rng(12345);//随机范围
	Point pt1;//定义随机的两个点
	Point pt2;//第二个点
	Mat bg(500, 500, CV_8UC3, Scalar(0, 0, 0));//绘制一个空白图像
	for (int i = 0; i < 100000; i++)//for循环
	{
		pt1.x = rng.uniform(0, 500);//定义第一个点的X坐标
		pt1.y = rng.uniform(0, 500);//定义第一个点的Y坐标
		pt2.x = rng.uniform(0, 500);//定义第二个点的X坐标
		pt2.y = rng.uniform(0, 500);//定义第二个点的Y坐标
		Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));//设置颜色的随机范围
		line(bg, pt1, pt2, color, 1, LINE_8);//将随机产生的直线绘制到空白图像上
		namedWindow("output", CV_WINDOW_AUTOSIZE);
		imshow("output", bg);
			if (waitKey(50) > 0)//设置停止时间
			{
				break;
			}

	}
}

你可能感兴趣的:(OpenCV)