• opencv基本的图像处理



    基本图像操作

    方法描述示例
    rect设定矩形框Rect rect(100, 100, 200, 200); Mat roi = src(rect);//提取src数据中矩形框标定的数据,此时roi指向了src图片对应的矩形数据,是指针!
    cvtColor图片类型转换cvtColor(src, gray, COLOR_BGR2GRAY); //BGR转灰度图
    threshold二进制阈值化threshold(gray, bin, 100, 255, THRESH_BINARY); //大于100全部设为255:白色; 小于100的设为0:黑色; threshold(gray,ibin, 100, 255, THRESH_BINARY_INV);//反二进制阈值化
    resize图片尺寸调整resize(src, des1024, Size(1024, 1024), 0, 0, INTER_LINEAR);
    pyrDown高斯金字塔,下采样pyrDown(src, gsrc);高斯金字塔(Gaussian pyramid):用来向下采样–下采样:图像成倍缩小
    pyrUp拉普拉斯金字塔,上采样pyrUp(src, lsrc);//拉普拉斯金字塔(Laplacian pyramid):用来从金字塔低层图像重建上层未采样图像 — 上采样:图像成倍增大
    addWeighted图像混合addWeighted(img1, a, img2, 1 - a, 80, dst); // addWeighted:加权; //a:img1的权重,取值范围[0,1]; dst:生成图像
    rotate图像旋转cv::rotate(img, rot, ROTATE_90_CLOCKWISE); // cv::rotate cv命名空间下的rotate函数,因此函数太容易被其他库中的函数名冲突。
    flip图像镜像cv::flip(img, fl, 1); // type:0(围绕x轴镜像),1(围绕y轴镜像),-1(围绕x和y轴做镜像)

    ROI区域

    #include 
    #include 
    #include 
    #include 
    using namespace cv;
    using namespace std;
    int main(int argc, char *argv[])
    {
    	Mat src = imread("1.png");
    	Rect rect(100, 100, 200, 200);
    	Mat roi = src(rect);  //浅拷贝,只赋值了矩阵头
    
    	namedWindow("src");
    	namedWindow("roi");
    	moveWindow("roi", 512, 0);  //图像显示窗口的位置移动
    	imshow("src", src);
    	imshow("roi", roi);
    	waitKey(0);
    	return 0;
    }
    
    //图像ROI提取 、 放回
    Mat binNowX = matFenge(rectBinX).clone();  //获取对应的数据
    binNowX.copyTo(BinaryTemplete(rectBinX));  //局部像素复制。原理是将(Mat *)binNowX拷贝到BinaryTemplete的rectBinX区域。
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    灰度图转换

    void RGBToGray(Mat &src, Mat &des)
    {
    	// GRay = (R*30 + G*59 + B*11 +50)/100
    	des.create(src.rows,src.cols,CV_8UC1);
    	for (int r = 0; r < src.rows; r++)
    	{
    		for (int c = 0; c < src.cols; c++)
    		{
    			Vec3b &m = src.at<Vec3b>(r, c);    //3位的向量,  Vec3b: BGR
    			int gray = (m[2] * 30 + m[1] * 59 + m[0] * 11 + 50) / 100;   //Mat:BGR
    			des.at<uchar>(r, c) = gray;
    		}
    	}
    }
    int main(int argc, char *argv[])
    {
    	Mat src = imread("1.png");
    	src.create(3000, 4000, CV_8UC3);   //重新创建src内容,  imread内容被删除了;为了体现多线程转换的优势,采用了大的图像。
    	Mat gray;
    	PrintMs("");
    	cvtColor(src, gray, COLOR_BGR2GRAY);  //采用了多线程,但是第一次由于启动线程等,耗时较久。424ms
    	PrintMs("cvtColor1");
    
    	cvtColor(src, gray, COLOR_BGR2GRAY);  //第二次转换则是多线程的优势,转换非常快。17ms
    	PrintMs("cvtColor2");
    	Mat mygray;
    	RGBToGray(src, mygray);    //自己转换,单个函数,耗时77ms
    	PrintMs("RGBToGray");
    
    	namedWindow("src");
    	namedWindow("gray");
    	namedWindow("mygray");
    
    	imshow("src", src);
    	imshow("gray", gray);
    	imshow("mygray", mygray);
    
    	waitKey(0);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    图像增益设计

    //
    ///@para a float 对比度 1.0~3.0
    ///@para b int 亮度 0~100
    void ChangeGain(Mat &src, Mat &des, float a, int b)
    {
    	//g(r,c) = a*f(r,c) + b
    	des.create(src.rows, src.cols, src.type());
    	for (int r = 0; r < src.rows; r++)
    	{
    		for (int c = 0; c < src.cols; c++)
    		{
    			for (int i = 0; i < 3; i++)
    			{
    				des.at<Vec3b>(r, c)[i] = saturate_cast<uchar>(a * src.at<Vec3b>(r, c)[i] + b);   //saturate_cast:防止溢出;超过uchar的值255就设定为255
    			}
    		}
    	}
    }
    int main(int argc, char *argv[])
    {
    	//调整对比度和亮度   ;   gain:增益 
    	Mat src = imread("2.jpg");
    	Mat des;
    	PrintMs("");
    	ChangeGain(src,des, 2.0,50);  //对比度:2.0;  亮度:+50;
    	PrintMs("ChangeGain");
    	Mat des2;
    	src.convertTo(des2, -1, 2.0, 50);  //opencv提供的函数,-1:负数代表与原图的类型一致; 性能比自己写的 函数性能高。
    	PrintMs("convertTo");
    
    	namedWindow("src");
    	namedWindow("des");
    	namedWindow("des2");
    	imshow("src", src);
    	imshow("des", des);
    	imshow("des2", des2);
    	waitKey(0);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    图像尺寸调整

    void xresize(Mat &src, Mat &des, Size size)  // Size:是cv命名空间的Size,很容易冲突的类型。
    {
    	des.create(size, src.type());
    	//映射的原图坐标
    	int sx, sy = 0;
    	float fx = (float)src.cols / des.cols;   // 原图列数(宽度)/目标图列数     
    	float fy = (float)src.rows / des.rows;  // 原图的行数(高度)/目标图的行数
    	for (int x = 0; x < des.cols; x++)
    	{
    		sx = fx * x + 0.5;   // int类型,四舍五入
    		for (int y = 0; y <des.rows; y++)
    		{
    			sy = fy * y + 0.5;
    			des.at<Vec3b>(y, x) = src.at<Vec3b>(sy, sx);  // 目标坐标的内容值等于原图相应坐标的内容值
    		}
    	}
    }
    int main(int argc, char *argv[])
    {
    	//图像尺寸调整算法,手动实现近邻算法;放大/缩小
    	Mat src = imread("1.png"); //512*512 256 1024
    	Mat img256,img1024,des256,des1024;
    	resize(src, des256, Size(256, 256), 0, 0, INTER_NEAREST);
    
    	PrintMs();
    	//xresize(src, img256, Size(256, 256));
    	//PrintMs("img256");
    	xresize(src, img1024, Size(1024, 1024));
    	//resize(src, img1024, Size(4024, 4024), 0, 0, INTER_NEAREST);
    	PrintMs("img1024");
    	//resize(src, des256, Size(1024, 1024), 0, 0, INTER_NEAREST);  // 近邻算法:INTER_NEAREST   , 简单的临近值拷贝:放大时边角处容易出现马赛克。原来一个像素点复制成了一个大的范围像素;缩小的话会有内容损失。
    	resize(src, des1024, Size(1024, 1024), 0, 0, INTER_LINEAR);   //双线性内插值算法(缺省使用的算法),不是简单的拷贝,而是做了临近的运算;输出像素是输入邻域像素的加权和。
    	//源图像位置在它附近的2*2区域4个临近像素的值通过加权平均计算得出的。低通滤波性质,使高频分量受损,图像轮廓可能会模糊一点。
    
    	PrintMs("des1024"); 
    
    	namedWindow("src");
    	//namedWindow("img256");
    	namedWindow("des1024");
    	namedWindow("img1024");
    	imshow("src", src);
    	imshow("img1024", img1024);
    	imshow("des1024", des1024);
    	moveWindow("des1024", 512, 0);  //图像显示窗口的位置移动
    
    	//imshow("img1024", img1024);
    	waitKey(0);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    图像混合,设定透明度

    int main(int argc, char *argv[])
    {
    	Mat img1 = imread("1.png");
    	Mat img2 = imread("2.png");
    	resize(img2, img2, img1.size());  //!!!图像大小必须一样;
    	Mat dst;
    	float a = 0.8;
    	addWeighted(img1, a, img2, 1 - a, 80, dst);   // addWeighted:加权; //a:img1的权重,取值范围[0,1]; dst:生成图像
    
    	namedWindow("blending");
    	imshow("blending", dst);
    	waitKey(0);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    图像合并,并列显示

    /************************************************************************
    注意:
    	Mat r1 = des(Rect(0, 0, width1, height));  //1号图,!!!: des(Rect())这个并不会新创建Mat r1数据,而是将r1这个指针对象指向des这个图,对des进行直接改变。
    	**********************************************************************/
    #include 
    int main(int argc, char *argv[])
    {
    	Mat img1 = imread("1.png");
    	Mat img2 = imread("2.png");
    	int height = img1.rows;  //设定两幅图像高度统一, 宽度不统一
    	int width1 = img1.cols;
    	int width2 = img2.cols;
    	// 将高度较高的图像等比缩放与低图像的高度一致
    	if (img1.rows > img2.rows)
    	{
    		height = img2.rows;
    		width1 = img1.cols * ((float)img2.rows / (float)img1.rows);  //等比缩放,高度一致,宽度等比例改变。
    		resize(img1, img1, Size(width1, height));
    	}
    	else if(img1.rows < img2.rows)
    	{
    		width2 = img2.cols * ((float)img1.rows / (float)img2.rows);
    		resize(img2, img2, Size(width2, height));
    	}
    	//创建目标Mat
    	Mat des;
    	des.create(height, width1 + width2, img1.type());  //创建, 谨记!!!该复用函数,此时参数第一个是高,第二个是宽
    	Mat r1 = des(Rect(0, 0, width1, height));  //1号图,!!!: des(Rect())这个并不会新创建Mat r1数据,而是将r1这个指针对象指向des这个图,对des进行直接改变。
    	img1.copyTo(r1);  // 将img1拷贝到r1区域,r1区域指针指向des,故而最终拷贝到了des定义的数据变量中。
    	Mat r2 = des(Rect(width1, 0, width2, height));
    	img2.copyTo(r2);
    
    	namedWindow("des");
    	imshow("des", des);
    	waitKey(0);
    	destroyAllWindows();
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
  • 相关阅读:
    java数据结构
    并查集及相关变形
    【YOLO】语义分割和实例分割(四)
    Python字典详解
    M41T62Q6F 一款具有报警功能的低功耗串行实时时钟(RTC)芯片
    2-STM32GPIO输入之按键
    Java | Maven(知识点查询)
    osgEarth::ElevationQuery的setMaxTilesToCache函数的作用
    Vue--整合SVG Icon图标--方法/实例
    【杂七杂八】Windows和Linux怎么配置环境变量
  • 原文地址:https://blog.csdn.net/qq_20467929/article/details/126086860