#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;
}