0
点赞
收藏
分享

微信扫一扫

OpenCV学习1------基础

JamFF 2022-04-21 阅读 56
opencv
#include<iostream>
#include<string>
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

//对图像的基本操作1:对Mat数组的操作,Mat图像的行数、列数、维数、尺寸、通道数、面积,访问像素点。
void base1(string pathname)
{
	//读取图片
	Mat img = imread(pathname);
	imshow("原图", img);
	//利用Mat类的成员函数获取图片的长和宽
	cout << "行数:" << img.rows << "	" << "列数:" << img.cols << endl;
	//成员变量dirms获取图像的维数,单通道是2维矩阵,多通道是3维矩阵。
	cout << "维数:" << img.dims << endl;
	cout << "类型:" << img.type() << endl;


	//Mat类的成员函数size()获得图片的尺寸
	cout << "尺寸:" << img.size() << endl;
	//成员函数channels()得到矩阵的通道数
	cout << "通道数:" << img.channels() << endl;
	//成员函数total()得到矩阵的长*宽
	cout << "面积:" << img.total() << endl;
	//利用成员函数at获取图像某一点处的像素值,缺点是速度很慢
	cout << int(img.at<uchar>(img.rows / 2, img.cols / 2))<<endl;
	cout << int(img.at<uchar>(Point(img.cols / 2, img.rows / 2)))<<endl;
	//成员函数ptr获得指向每一行首地址的指针,成员函数isContinous()判定行与行之间是否是连续存储
	//连续存储的话可以直接按照第一行的地址来访问所有的row*col个像素值
	//访问图片中每个像素点的值,实测这种方法慢的要死
	for (int i = 0; i < img.rows; i++)
	{
		const uchar *ptr = img.ptr<uchar>(i);
		for (int j = 0; j < img.cols; j++)
		{
			cout << i<<">>>"<<int(ptr[j]) << " , ";
		}
		cout << endl;
	}
	cout << "图像是否有行间隔:" << img.isContinuous()<< endl;
	//好像只有下面这种情况t才可以输出出来
	if (img.isContinuous())
	{
		const uchar *ptr = img.ptr<uchar>(0);
		for (int i = 0; i < (img.rows*img.cols)/10000; i++)
		{
			cout << int(ptr[i]) << " , ";
		}
		cout << endl;
	}
	//成员变量step[],step[0]代表每一行所占的字节数,如果有间隔,间隔也作为字节数的一部分
	//step[1]代表每一个数据所代表的字节数
	//成员变量data是指向第一个数值的指针,类型为uchar
	cout << "每一行所代表的字节数:" << img.step[0] << endl;
	cout << "每一个数据所代表的字计数:" << img.step[1] << endl;
	cout << "第一个数据:" << int(*img.data) << endl;
	//用指针的方法访问具体像素点的值,速度是最快的
	//访问(col,row)点的像素值>>*((int*)(img.data+img.step[0]*row+img.step[1]*col))
	for (int i = 0; i < img.rows; i++)
	{
		for (int j = 0; j < img.cols; j++)
		{
			cout << endl;
			cout << i << ">>>" << *((int*)(img.data + img.step[0] * i + img.step[1] * j)) << " , ";
		}
	}
	//向量类Vec,构建一个长度为3,数据类型为int且初始化的列向量(默认是列向量)
	//通过成员函数rows和cols访问查看行列数,利用[]或()访问向量中的值
	Vec<int, 3> vi(31, 21, 18);
	cout << "向量的行数:" << vi.rows << endl;
	cout << "向量的列数:" << vi.cols << endl;
	cout << "第二个元素:" << vi[2] << endl;

	
	waitKey(0);
	destroyAllWindows();
}

//对图像的基本操作2:多通道与图片的分离、合并,ROI的截取、矩阵行和列的获取。
int base2(string pathname)
{
	//读取图片
	Mat img = imread(pathname);
	if (img.empty())
		return -1;
	//imshow("原图", img);
	//多通道图像的分离
	vector<Mat> planes;
	split(img, planes);
	Mat B = planes[0];
	Mat G = planes[1];
	Mat R = planes[2];	
	//多通道合并
	Mat mat;
	Mat planes1[] = { planes[0],planes[1] ,planes[2] };
	merge(planes1, 3, mat);
	//用成员函数row(i)和col(j)获得矩阵的第i行和第j列(返回的仍是Mat矩阵)
	Mat mr = R.row(1);
	Mat mc = R.col(1);
	//cout << "行1:" << mr << endl << "列1:" << mc << endl;
	//利用成员函数rowRange和colRange得到矩阵的连续行或连续列
	//Range(int start, int end)产生左闭右开的连续序列,用作上面两个成员函数的参数
	//修改截取的部分图像,原本图像对应点也会发生变化,因为col,row,rowrange,colRange返回的矩阵是指向原矩阵的
	Mat r_range = R.rowRange(Range(2, 7));
	Mat r_c_range = r_range.colRange(Range(9, 20));
	cout << r_c_range << endl;
	//成员函数clone和copyTo用于将矩阵克隆或复制一份
	r_range = R.rowRange(Range(2, 4)).clone();
	R.rowRange(2, 4).copyTo(r_range);
	//用Rect截取图像的ROI区域,截取的矩形区域是指向原矩阵的
	Mat ROI1 = R(Rect(Point(100, 100), Point(1000, 1000)));
	Mat ROI2 = R(Rect(Point(100, 100), Size(900, 900)));
	Mat ROI3 = R(Rect(100, 100, 900, 900));
	int i;
	cin >> i;
	return 0;     
}
//掩膜法创建扇形ROI
vector<Mat> creatROIOfSector(Mat img)
{
	Mat mask1 = Mat::zeros(img.size(), CV_8UC1);
	Mat mask2 = Mat::zeros(img.size(), CV_8UC1);
	Mat mask3 = Mat::zeros(img.size(), CV_8UC1);
	Mat imgout = img.clone();
	//-1为填充
	ellipse(mask1, Point(200, 200),Size(50,50), 0, -30, 30, Scalar(255),-1);
	ellipse(mask2, Point(200, 200), Size(50, 50), 0, 150, 210, Scalar(255), -1);
	ellipse(mask3, Point(200, 200), Size(30, 30), 0, -30, 30, Scalar(255), -1);
	ellipse(mask2, Point(200, 200), Size(30, 30), 0, 150, 210, Scalar(0), -1);
	Mat ellipseROI1, ellipseROI2;
	imgout.copyTo(ellipseROI1,mask1);
	//ellipseROI1 = imgout & mask1;
	imgout.copyTo(ellipseROI2, mask2);
	double pi = 3.141592653589793;
	double area = CV_PI * (50*50 - 30*30)*0.16666666666667;
	double  ellipseROI_L_mean = sum(ellipseROI1)[0] / area;
	double  ellipseROI_R_mean = sum(ellipseROI1)[0] / area;
	vector<Mat> ellipse;
	ellipse.push_back(ellipseROI1);
	ellipse.push_back(ellipseROI1);
	return ellipse;

}
int main()
{
	Mat img = imread("D://img_test//CAM1//20211123_040500_0278_7873.bmp");
	//注意这种赋值(构造)方式只是复制了Mat类的矩阵头,矩阵指针指向的是同一个地址
	//因此如果通过某一个Mat类变量修改了矩阵中的数据,另一个变量中的数据也会发生改变。
	Mat A = img;
	for (int i = 0; i < A.rows/10; i++)
	{
		for (int j = 0; j < A.cols/10; j++)
		{
			*((int*)(A.data + A.step[0] * i + A.step[1] * j))=0;
		}
	}
	Mat imgout;
	resize(img, imgout,Size(img.cols /4, img.rows/ 4));
	cvtColor(imgout, imgout, COLOR_BGR2GRAY);
	creatROIOfSector(imgout);
	waitKey(0);
	return 0;
}
举报

相关推荐

0 条评论