OpenCV小白学习笔记(三)图像处理

图像处理(三)

Mat对象

**1.Mat对象与IplImage对象
2.Mat对象使用
3.Mat定义数组**

Mat对象OpenCV2.0之后引进的图像数据结构、自动分配内存、不存在内存泄漏的问题,是面向对象的数据结构。分了两个部分,头部与数据部分
IplImage是从2001年OpenCV发布之后就一直存在,是C语言风格的数据结构,需要开发者自己分配与管理内存,对大的程序使用它容易导致内存泄漏问题

Mat对象常用构造函数

1.Mat()
创建一个Mat对象,在构造时不进行任何操作

//创建一个Mat对象
Mat img;

2.Mat(int rows , int cols,int type)
根据用户指定的行数、列数以及类型创建一个Mat对象

//创建一个3*3的图像,每个通道8个字节长度 uchar类型,通道数量为1的Mat对象
Mat img= Mat(3,3,CV_8UC1);

3.Mat(Size size , int type)
根据用户指定的大小以及类型,创建一个Mat对象

//读取本地图像返回给Mat对象src,根据src的大小,创建一个3*3的图像,每个通道8个字节长度 uchar类型,通道数量为1的Mat对象
Mat src = imread("E:/OpenCV/OpenCVPicture/horse.png");
Mat img= Mat(src.size(),CV_8UC1);

4.Mat(int rows , int cols,int type,const Scalar &s)
根据用户指定的行数、列数以及类型创建一个Mat对象并初始化每个像素的值,向量长度必须对应通道数

//创建一个3*3的图像,每个通道8个字节长度 uchar类型,通道数量为3的Mat对象,并将初始颜色设为(127,0,255)
Mat img= Mat(3,3,CV_8UC3,Scalar(127,0,255))

5.Mat(Size size , int type , const Scalar &s)
根据用户指定的大小以及类型,创建一个Mat对象并初始化每个像素的值,向量长度必须对应通道数

//读取本地图像返回给Mat对象src,根据src的大小,创建一个3*3的图像,每个通道8个字节长度 uchar类型,通道数量为3的Mat对象,并将初始颜色设为(127,0,255)
Mat src = imread("E:/OpenCV/OpenCVPicture/horse.png");
Mat img= Mat(src.size(),CV_8UC3,Scalar(127,0,255));

6.数组构造
使用矩阵数据构造一个Mat对象

//构成3*3
// 0  -1  0
// -1  5  -1
//  0  -1  0
//的Mat图像
Mat mat = (Mat_(3,3)<<0,-1,0,-1,5,-1,0,-1,0);

Mat对象常用方法

1.void copyTo(Mat mat)
Mat对象深拷贝

//将src对象的图像复制到dst对象中
Mat src = imread("E:/OpenCV/OpenCVPicture/horse.png");
Mat dst;
src.copyTo(dst);

2.void converto(Mat dst,int type)
Mat对象转化函数

//将src转化成每个通道8个字节长度 uchar类型,通道数量为3的Mat对象(可以在函数后面附加因子进行计算)
Mat src = imread("E:/OpenCV/OpenCVPicture/horse.png");
Mat dst;
str.converto(dst,CV_8UC3);

3.Mat clone()
Mat对象深拷贝

//将src对象的图像复制到dst对象中
Mat src = imread("E:/OpenCV/OpenCVPicture/horse.png");
Mat dst;
dst.clone(src);

4.int channels()
获取当前图像的通道数

//获取src的通道数
Mat src = imread("E:/OpenCV/OpenCVPicture/horse.png");
int channel = src.channels();

5.int depth()
获取当前图像的深度

//获取src的深度
Mat src = imread("E:/OpenCV/OpenCVPicture/horse.png");
int channel = src.depth();

6.bool empty()
判断图像是否为空

Mat src = imread("E:/OpenCV/OpenCVPicture/horse.png");
Mat dst;
src.empty(); //false
dst.empty(); //true

7.uchar* ptr(i = 0)
获取当前图像的指针

//获取src图像的第一行对应指针
Mat src = imread("E:/OpenCV/OpenCVPicture/horse.png");
const unchar* fisrtRow = src.ptr(0);

8.Mat zeros(int rows,int cols,int type)
创建全0的Mat对象

//创建2*2每个通道8个字节长度 uchar类型,通道数量为1的全0 Mat对象
Mat img = Mat::zeros(2,2,CV_8UC1)

9.Mat eye(int rows,int cols,int type)
创建对角线为1的Mat对象

//创建2*2每个通道8个字节长度 uchar类型,通道数量为1的对象线为1 Mat对象
//1  0
//0  1
Mat img = Mat::eye(2,2,CV_8UC1)
  1. _Tp& at(int row,int col)
    获取图像上一个点的像素,可对其进行获取或者修改,灰度图像和RGB图像有区别

    /对于灰度图像进行像素点的获取以及修改/
    //打开原始图像
    Mat src = imread(“E:/OpenCV/OpenCVPicture/horse.png”);
    Mat gray_src;
    //将RGB图像转化成灰度图像
    cvtColor(src,gray_src,CV_BGR2GRAY);
    //获取灰度图像在 (0,0)处的像素值
    uchar test = gray_src.at(0,0);
    //修改灰度图像在 (0,0)处的像素值
    gray_src.at(0,0) = 0

    /对于RGB图像进行像素点的获取以及修改/
    Mat src = imread(“E:/OpenCV/OpenCVPicture/horse.png”);
    //获取RGB像素
    uchar blue= src.at(0,0)[0]; //蓝色通道像素值
    uchar green= src.at(0,0)[1]; //绿色通道像素值
    uchar red = src.at(0,0)[2]; //红色通道像素值
    //修改RGB像素
    src.at(0,0)[0] = 0; //修改蓝色通道像素为0
    src.at(0,0)[1] = 0; //修改绿色通道像素为0
    src.at(0,0)[2] = 0; //修改红色通道像素为0

Mat对象使用-四个要点

1.输出图像的内存是自动分配的
2.使用OpenCV的C++接口,不需要考虑内存分配问题
3.赋值操作和拷贝构造函数只会复制头部分
4.使用clone与copyTo两个函数实现数据完全复制

Mat对象创建(补充)

cv::Mat::Mat构造函数
Mat M(2,2,CV_8UC3, Scalar(0,0,255))
其中前两个参数分别表示行(row)跟列(column)、第三个CV_8UC3中的8表示每个通道占8位、U表示无符号、C表示Char类型、3表示通道数目是3,第四个参数是向量表示初始化每个像素值是多少,向量长度对应通道数目一致

创建多维数组cv::Mat::create
int sz[3] = {2,2,2};
Mat L(3,sz, CV_8UC1, Scalar::all(0));

cv::Mat::create实现

Mat M;
M.create(4, 3, CV_8UC2);
M = Scalar(127,127);
cout << "M = " << endl << " " << M << endl << endl;
uchar* firstRow = M.ptr<uchar>(0);
printf("%d", *firstRow);

代码案例

#include  
#include  
#include 
#include 

using namespace cv;
using namespace std;
int main(int argc, char** args) {
     
Mat image = imread("D:/test.jpg", IMREAD_GRAYSCALE);
if (image.empty()) {
     
cout << "could not find the image resource..." << std::endl;
return -1;
}
namedWindow("My Image", CV_WINDOW_AUTOSIZE);
imshow("My Image", image);

Mat M;
M.create(4, 3, CV_8UC2);
M = Scalar(127,127);
cout << "M = " << endl << " " << M << endl << endl;
uchar* firstRow = M.ptr<uchar>(0);
printf("%d\n", *firstRow);

Mat C = (Mat_<double>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
cout << "C = " << endl << " " << C << endl << endl;

waitKey(0);
return 0;
}

图像操作

1.读写图像
2.读写像素
3.修改像素值

读写图像

imread 可以指定加载为灰度或者RGB图像
Imwrite 保存图像文件,类型由扩展名决定

读写像素

1.读一个GRAY像素点的像素值(CV_8UC1)
Scalar intensity = img.at(y, x);
或者 Scalar intensity = img.at(Point(x, y));

2.读一个RGB像素点的像素值
Vec3f intensity = img.at(y, x);
float blue = intensity.val[0];
float green = intensity.val[1];
float red = intensity.val[2];

修改像素值

灰度图像
img.at(y, x) = 128;

RGB三通道图像
img.at(y,x)[0]=128; // blue
img.at(y,x)[1]=128; // green
img.at(y,x)[2]=128; // red

空白图像赋值
img = Scalar(0);

ROI选择
Rect r(10, 10, 100, 100);
Mat smallImg = img®;

Vec3b与Vec3F

Vec3b对应三通道的顺序是blue、green、red的uchar类型数据。

Vec3f对应三通道的float类型数据

把CV_8UC1转换到CV32F1实现如下:
src.convertTo(dst, CV_32F);

代码案例

#include  
#include  
#include 
#include 

using namespace cv;
using namespace std;
int main(int argc, char** args) {
     
Mat image = imread("D:/test.jpg", IMREAD_COLOR);
if (image.empty()) {
     
cout << "could not find the image resource..." << std::endl;
return -1;
}

int height = image.rows;
int width = image.cols;
int channels = image.channels();
printf("height=%d width=%d channels=%d", height, width, channels);
for (int row = 0; row < height; row++) {
     
       for (int col = 0; col < width; col++) {
     
                if (channels == 3) {
     
                         image.at<Vec3b>(row, col)[0] = 0; // blue
                         image.at<Vec3b>(row, col)[1] = 0; // green
                }
         }
}

namedWindow("My Image", CV_WINDOW_AUTOSIZE);
imshow("My Image", image);
waitKey(0);
return 0;
}

你可能感兴趣的:(opencv,opencv,计算机视觉)