OpenCV总结之一_图像处理基本操作

目录:
*第一节——基础——加载imread、修改、显示imshow、保存imwrite
*第二节——矩阵的掩模操作filter2D+++代码的运行时间getTickCount
*第三节——Mat对象create、clone、copyTo、cvtColor、cout
*第四节——图像操作——访问图像像素点进行反差操作bitwise_not
*第五节——图像混合——两张大小相等类型相同的图像进行线性混合操作addWeighted
*第六节——提高图像亮度与对比度
*第七节——绘制形状与文字-线line、矩形rectangle、椭圆ellipse、圆circle、多边形fillPoly、随机线与文字
*第八节——图像模糊-去噪-均值blur、高斯GaussianBlur、中值medianBlur、双边bilateralFilter
*第九节——形态学操作——膨胀dilate和腐蚀erode
*第十节——形态学操作morphologyEx——开操作、闭操作、形态学梯度、顶帽、黑帽
*第十一节——形态学操作应用-提取水平与垂直线
*第十二节——图像金字塔——图像上采样pyrUp(zoom in放大)和降采样pyrDown(zoom out缩小)
*第十三节——基本阈值操作threshold
*第十四节——自定义线性滤波——Robert、Sobel、拉普拉斯算子、filter2D
*第十五节——边缘处理——copyMakeBorder用途:在卷积时边界的处理方式有4种类型
*第十六节——Sobel——边缘处理
*第十七节——Laplacian——边缘处理
*第十八节——Canny——边缘处理
*第十九节——霍夫变换——直线变换HoughLinesP
*第二十节——霍夫变换——圆变换HoughCircles
*第二十一节——像素重映射remap
*第二十二节——直方图均衡化equalizeHist
*第二十三节——直方图计算calcHist
*第二十四节——直方图比较compareHist
*第二十五节——直方图反向投影calcBackProject
*第二十六节——模板匹配matchTemplate
*第二十七节——轮廓发现findContours
*第二十八节——凸包convexHull
*第二十九节——轮廓周围绘制矩形框和圆形框
*第三十节——图像矩moments、面积contourArea, 弧长arcLength
*第三十一节——点多边形测试
*第三十二节——点多边形测试

///第一节——基础——加载imread、修改、显示imshow、保存imwrite*///

//添加头文件
#include<opencv2/opencv.hpp>
#include<iostream>
#include<math.h>
#include <opencv2/core/core.hpp> 
#include <opencv2/imgcodecs.hpp> 
#include <opencv2/highgui/highgui.hpp>
//命名空间
using namespace cv;
using namespace std;
//程序入口
int main(int argc, char** argv)
{
   
	//加载图像
	Mat src = imread("E:/images/test.jpg");
	if (src.empty()) {
   printf("error\n");	return -1;} 
	//if(!src1.data) {cout << "error..." << endl;  return -1;}//不同的表达方式
	///CV_Assert(testImage.depth() == CV_8U);//若括号中的表达式值为false,则返回一个错误信息_同上一句的效果
	namedWindow("opencv setup demo", CV_WINDOW_AUTOSIZE);//创建一个显示窗口
	imshow("opencv setup demo", src);//显示图像
	//修改图像
	Mat dst;
	cvtColor(src, dst, CV_BGR2HSV);//色彩空间转换
	imshow("output window", dst);//显示修改后的图像
    //保存图像
	imwrite("E:/images/repair.png", dst);
	waitKey(0);
	return 0;
}

///第二节——矩阵的掩模操作filter2D+++代码的运行时间getTickCount*/

int main(int argc, char** argv)
{
   
	//代码运行开始时间
	double t = getTickCount();
	//使用Filter2D函数——掩模操作
	Mat kernel = (Mat_<char>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
	filter2D(src, dst, src.depth(), kernel);
    //filter2D(src, csrc, -1, kernel);//-1默认和src的深度一样
	//代码运行时间=结束时间-开始时间       //转换时间单位并输出代码运行时间
	double timeconsume = (getTickCount() - t) / getTickFrequency();
	printf("timeconsume %.2f\n", timeconsume);//输出消耗的时间
}

///第三节——Mat对象create、clone、copyTo、cvtColor、cout*/

int main(int argc, char** argv)
{
   
	//创建一个与输入图像src大小、类型一致的图像,且初始化像素为红色
	Mat dst = Mat(src.size(), src.type(), Scalar(0, 0, 255));//初始化的像素值,(0, 0, 255)表示红色
	//同上的另一种创建方法
	Mat m1;
    m1.create(src.size(), src.type());
	m1 = Scalar(0, 0, 255);    
	//克隆
	Mat dst = src.clone();
	//复制
	Mat dst;//clone  copyTo  两种
	src.copyTo(dst);  
    //将图像转为灰度图像,并显示:输入图像和输出图像的通道结果
	cvtColor(src, dst, CV_BGR2GRAY);
	printf("input image channels : %d\n", src.channels());  //3通道
	printf("output image channels : %d\n", dst.channels()); //1通道
    //显示输出图像的宽和高以及输出图像第一个像素值
	cvtColor(src, dst, CV_BGR2GRAY);
	int cols = dst.cols;//dst的全部列(宽)
	int rows = dst.rows;//dst的全部行(高)
	printf("rows : %d cols : %d\n", rows, cols);
	const uchar* firstRow = dst.ptr<uchar>(0);//访问图像的像素值
	printf("fist pixel value : %d\n", *firstRow);//第一个像素值是多少
    //定义一个3×3的图像,数据结构为CV_8UC3
	Mat M(3, 3, CV_8UC3, Scalar(0,0,255));//3通道,(0,0,255)
	imshow("out image", M);
	cout << "M =" << endl << M << endl;//一种打印方式
    //定义一个100×100的图像,数据结构为CV_8UC1
	Mat M(100, 100, CV_8UC1, Scalar(127));   //1通道   127
	cout << "M =" << endl << M << endl;
    //创建新的窗口——全部初始化为0,图像为黑漆漆的一片,类似于眼睛
	Mat m1 = Mat::zeros(2, 2, CV_8UC1);//参数(row,col,type)(行-高,列-宽,类型)
	Mat m2 = Mat::zeros(src.size(), src.type());//和原图大小一样
	Mat m3 = Mat::eye(2, 2, CV_8UC1);
	cout << "m2 =" << endl << m2 << endl;
}

///第四节——图像操作——访问图像像素点进行反差操作bitwise_not*/

int main(int argc, char** args)
{
   
	//单通道图像反差
	Mat grayImg;
	cvtColor(src, grayImg, CV_BGR2GRAY);//cvtColor(src, grayImg, COLOR_BGR2GRAY);
	// int height = grayImg.rows;//行
	// int width = grayImg.cols;//列
	// for (int row = 0; row < height; row++)
	// {
   
		// for (int col = 0; col < width; col++)
		// {
   
			// int gray = grayImg.at<uchar>(row, col);
			// grayImg.at<uchar>(row, col) = 255 - gray;//反差之后的像素
		// }
	// }
	bitwise_not(grayImg, grayImg); //调用函数等同于for循环的内容  反差图片
	//三通道——彩色图像的反差处理
	Mat dst;
	dst.create(src.size(), src.type());
	int height3 = src.rows;  int width3 = src.cols;  int channels = src.channels();//获取通道
	printf("height=%d width=%d channels=%d\n", height, width, channels);
	// for (int row = 0; row < height3; row++)
	// {
   
		// for (int col = 0; col < width3; col++)
		// {
   
			// if (channels == 1)
			// {
   
				// int gray = grayImg.at<uchar>(row, col);
				// grayImg.at<uchar>(row, col) = 255 - gray;//反差之后的像素
			// }
			// else if (channels == 3)
			// {
   
				// int b = src.at<Vec3b>(row, col)[0];//blue
				// int g = src.at<Vec3b>(row, col)[1];//green
				// int r = src.at<Vec3b>(row, col)[2];//red
				// dst.at<Vec3b>(row, col)[0] = 255 - b;
				// dst.at<Vec3b>(row, col)[1] = 255 - g;
				// dst.at<Vec3b>(row, col)[2] = 255 - r;
			// }
		// }
	// }
	bitwise_not(src, dst); //调用函数等同于for循环的内容  反差图片
}

///第五节——图像混合——两张大小相等类型相同的图像进行线性混合操作addWeighted*/

int main(int argc, char** argv) 
{
   
	double alpha = 0.5;
	if (src1.rows == src2.rows && src1.cols == src2.cols && src1.type() == src2.type())
	{
   
		//add(src1,src2,dst,Mat());  //直接添加的效果
		//multiply(src1, src2, dst, 1.0);  //相乘的效果
		addWeighted(src1, alpha, src2, (1.0 - alpha), 0.0, dst);//线性混合操作	
	}
	else
	{
   
		printf("could not blend images , the size of images is not same...\n");
		return -1;
	}
}

///第六节——提高图像亮度与对比度*/

int main(int argc, char** argv)
{
   
	int height = src.rows;
	int width = src.cols;
	Mat dst = Mat::zeros(src.size(), src.type());//创建一个和原图像大小和类型一致的空白图像,像素初始化为0
	float alpha = 1.5;
	float beta = 10;
	Mat m1;
	src.convertTo(m1, CV_32F);
	for (int row = 0; row < height; row++)
	{
   
		for (int col = 0; col < width; col++) 
		{
   
			if (src.channels() == 3)
			{
   
				float b = m1.at<Vec3f>(row, col)[0];// blue
				float g = m1.at<Vec3f>(row, col)[1]; // green
				float r = m1.at<Vec3f>(row, col)[2]; // red
				// output
				dst.at<Vec3b>(row, col)[0] = saturate_cast<uchar>(b*alpha + beta);
				dst.at<Vec3b>(row, col)[1] = saturate_cast<uchar>(g*alpha + beta);
				dst.at<Vec3b>(row, col)[2] = saturate_cast<uchar>(r*alpha + beta);
			}
			else if (src.channels() == 1)
			{
   
				float v = src.at<uchar>(row, col);
				dst.at<uchar>(row, col) = saturate_cast<uchar>(v*alpha + beta);
			}
		}
	}
}

///第七节——绘制形状-线line、矩形rectangle、椭圆ellipse、圆circle、多边形fillPoly、随机线与文字*/

Mat src;//定义的全局变量
const char* drawdemo_win = "draw shapes and text demo";
//函数声明
void MyLines();/*线*/      void MyRectangle();/*矩形*/    void MyEllipse();/*椭圆*/  
void MyCircle();/*圆*/     void MyPolygon();/*多边形*/    void RandomLineDemo();/*随机线*/
int main(int argc, char** argv)
{
   
	//函数调用
	MyLines();
	MyRectangle();
	MyEllipse();
	MyCircle();
	MyPolygon();//多边形
	//绘制文字
	putText(src, "Hello OpenCV", Point(300, 300),CV_FONT_HERSHEY_COMPLEX, 1.0,Scalar(12, 23, 200), 3, 8);
	RandomLineDemo();
}
//函数实现
void MyLines() 
{
   
	Point p1 = Point(20, 30);
	Point p2;
	p2.x = 400;
	p2.y = 400;
	Scalar color = Scalar(0, 0, 255);//红色
	line(src, p1, p2, color, 1, LINE_AA);//1表示线宽
}
void MyRectangle()
{
   
	Rect rect = Rect(200, 100, 300, 300);
	Scalar color = Scalar(255, 0, 0);//蓝色
	rectangle(src, rect, color, 2, LINE_8);
}
void MyEllipse()
{
   
	Scalar color = Scalar(0, 255, 0);//绿色
    /*空心椭圆(src,点中心,尺寸轴,双角度,双起始角,双终止角,颜色,线宽,线型,int shift=0)*/
	ellipse(src,Point(src.cols / 2, src.rows / 2),Size(src.cols / 4, src.rows / 8),
		    90, 0, 360, color, 2, LINE_8);
}
void MyCircle()
{
   
	Scalar color = Scalar(0, 255, 255);
	Point center = Point(src.cols / 2, src.rows / 2);
	circle(src, center, 150, color, 2, 8);
}
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* ppts[] = {
    pts[0] };//多边形的顶点
	int npt[] = {
    5 };//要绘制的多边形顶点数目
	Scalar color = Scalar(255, 12, 255);//颜色
	fillPoly(src, ppts, npt, 1, color, 8);//1表示画一个多边形-实心的
}
void RandomLineDemo()
{
   
	RNG rng(12345);//随机数生成函数RNG   12345是随机种子
	Point pt1;
	Point pt2;
	Mat bg = Mat::zeros(src.size(), src.type());//创建一张空白图片,纯黑色
	for (int i = 0; i < 100000; i++)
	{
   
		pt1.x = rng.uniform(0, src.cols);
		pt2.x = rng.uniform(0, src.cols);
		pt1.y = rng.uniform(0, src.rows);
		pt2.y = rng.uniform(0, src.rows);
		Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
		if (waitKey(50) > 0) //随时可以停止的命令
		{
   
			break;
		}
		line(bg, pt1, pt2, color, 1, 8);
	}
}

///第八节——图像模糊-去噪-均值blur、高斯GaussianBlur、中值medianBlur、双边bilateralFilter*/

int main(int argc, char** argv)
{
   
	//均值模糊
	blur(src, dst, Size(11, 11), Point(-1, -1));//Point(-1, -1)表示默认正中心
    //高斯模糊
	GaussianBlur(src, gblur, Size(11, 11), 11, 11);//Size(x,y),x,y必须是正数而且是奇数
    //中值滤波  对椒盐噪声有很好的效果
	medianBlur(src, dst, 3);
	//双边滤波  立体感更强
	bilateralFilter(src, dst, 15, 200, 
  • 0
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

柠萌初夏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值