图像处理openCV基础使用

Posted pigcv

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了图像处理openCV基础使用相关的知识,希望对你有一定的参考价值。

openCV 基础学习

with:于士琪openCV基础


env:opencv3.4.0+vc2017集成开发环境

图像的表示:矩阵

1. 灰度矩阵 <br>
2. 彩色(多通道)如RGB图像,RGB图像的通道顺序是BGR

Mat

class CV_EXPORTS Mat
    {
    public:
    //一系列函数
    ...
    /* flag 参数中包含许多关于矩阵的信息,如:
    -Mat 的标识
    -数据是否连续
    -深度
    -通道数目
    */
    int flags;
    //矩阵的维数,取值应该大于或等于 2
    int dims;
    //矩阵的行数和列数,如果矩阵超过 2 维,这两个变量的值都为-1
    int rows, cols;
    //指向数据的指针
    uchar* data;
    //指向引用计数的指针
    //如果数据是由用户分配的,则为 NULL
    int* refcount;
    24
    //其他成员变量和成员函数
    ...
    };
    

创建Mat对象(构造方法):

  1. Mat M(3,2,CV_8UC3,Scalar(0,0,255));

    //创建一个行数为3,列数为2的图像,图像元素是8位无符号整数,3个通道,初始值为0,0,255,为全红
  2. Mat对象的type是:CV_8UC1,CV_16SC1,…,CV_64FC4 等
  3. create()方法
  4. at()方法:读矩阵中某个像素,或对某个元素赋值

    uchar value = grayim.at<uchar>(i,j);//读出第 i 行第 j 列像素值
    grayim.at<uchar>(i,j)=128; //将第 i 行第 j 列像素值设置为 128
  5. 迭代器使用 MatIterator
    ```

    include

    include

    using namespace std;
    using namespace cv;

int main() {
Mat g(600, 800, CV_8UC1);
Mat c(600, 800,CV_8UC3);
MatIterator_

}

6. 选取图像局部区域:是浅复制,注意复制前后共享内存区域。<br>
    i. 单行、列选取
        row()/col()<br>
     ```    
        Mat Mat::row(int i) const
        Mat Mat::col(int j) const
    ```
    ii. 多行、多列<br>
        Range类:<br>
        
    ```
        class Range
        {
        public:
        int start, end; //从start行(列)到end行(列),左闭右开
        
        static .. all(); //all方法,静态方法,表示所有的行、列
        
        };
    ```
        如:
    ```
        Mat A = Mat::eye(10,10,CV_32S);
        //提取第一列到第三列
        Mat B = A(Range::all(),Range(1,3));
        //提取第一行到第三行
        Mat C = A(Range(1,3),Range::all());
        
    ```
7. Mat_类:Mat类的封装:<br>
        使用 Mat_类,那么就可以在变量声明时确定元素的类型,访问元素时不再需要指定元素类型,即使得代码简洁
        
### 图像读写:读写图像文件:<br>

1. imread

Mat imread(const string& filename, int flags=1 );

imread()函数返回的是 Mat 对象.
如果读取文件失败,则会返回一个空矩阵,即 Mat::data 的值是 NULL。执行 imread()之后,需要检查文件是否成功读入,可以使用 Mat::empty()函数进行检查。
        flag 参数值有三种情况:
        ?  flag>0,该函数返回 3 通道图像,如果磁盘上的图像文件是单通道的灰度图像,则会被强制转为 3 通道;
        ?  flag=0,该函数返回单通道图像,如果磁盘的图像文件是多通道图像,则会被强制转为单通道;
        ?  flag<0,则函数不对图像进行通道转换。
2. imwrite
bool imwrite(const string& filename, InputArray image,const vector<int>& params=vector<int>())

3. 读入一副图像,然后对图像进行 Canny 边缘操作:
#include<iostream>
#include<opencv2\opencv.hpp>
using namespace std;
using namespace cv;

int  main() {
    Mat im = imread("C:\\Users\\duye\\Desktop\\2.jpg",1);
if (im.empty()) {
    cout << "Can not load image!" << endl;
    return -1;
}
Mat result;
Canny(im, result, 50, 100);
imwrite("C:\\Users\\duye\\Desktop\\1.jpg",result);

return 0;

}

### 视频操作:
1. 读视频:
VideoCapture 既可以从视频文件读取图像,也可以从摄像头读取图像<br>
从文件/视频读视频:
#include <iostream>
#include "opencv2/opencv.hpp"
using namespace std;
using namespace cv;
int main(int argc, char** argv)
{
//打开视频文件
    VideoCapture cap("video.short.raw.avi");
    //根据摄像头ip 获取实时视频流
    //注意这里不再使用定义了的返回的视频流,直接使用摄像头ip就好
    //String videoUrl = "...";
    //VideoCapture cap;
    //cap.open(videoUrl);
    //检查是否成功打开
    if(!cap.isOpened())
    {
        cerr << "Can not open a camera or file." << endl;
        return -1;
    }
    Mat edges;
    //创建窗口
    namedWindow("edges",1);
    for(;;)
    {
        Mat frame;
        //从 cap 中读一帧,存到 frame
        cap >> frame;
        //如果未读到图像
        if(frame.empty())
            break;
        //将读到的图像转为灰度图
        cvtColor(frame, edges, CV_BGR2GRAY);
        //进行边缘提取操作
        Canny(edges, edges, 0, 30, 3);
        //显示结果
        imshow("edges", edges);
        //等待 30 秒,如果按键则推出循环
        if(waitKey(30) >= 0)
            break;
    }
    //退出时会自动释放 cap 中占用资源
    return 0;
}

2. 写视频<br>
读取摄像头视频,写入文件中保存
#include <opencv2/core/core.hpp>  
#include <opencv2/highgui/highgui.hpp>  
using namespace cv;
void main()
{
    String url = "http://192.168.1.1:8080";
VideoCapture cap();
cap.open(url);
double rate = 25.0;//视频的帧率
Size videoSize(1280,960);
VideoWriter writer("VideoTest.avi", CV_FOURCC(‘M‘, ‘J‘, ‘P‘, ‘G‘), rate, videoSize);
Mat frame;
while (capture.isOpened())
{
    capture >> frame;
    writer << frame;
    imshow("video", frame);
    if (waitKey(20) == 27)//27是键盘摁下esc时,计算机接收到的ascii码值
    {
        break;
    }
}
}

```

后续我会给出目前比较流行的使用opencv实现人脸识别的具体实现。以上。

以上是关于图像处理openCV基础使用的主要内容,如果未能解决你的问题,请参考以下文章

pyhton—opencv直线检测(HoughLines)找到最长的一条线

1.opencv—图像处理基础

以代码为基础的opencv-python学习 图像模糊

以代码为基础的opencv-python学习 图像二值化

OpenCV(C++)图像处理基础开篇00

图像处理openCV基础使用