第五讲-5.3.1OpenCV的基本使用方法

一、CMakeLists文件

cmake_minimum_required(VERSION 3.15)
project(imageBasics)

set(CMAKE_CXX_STANDARD 14)
#寻找指定版本的OpenCV库
find_package(OpenCV REQUIRED)
#添加OpenCV头文件
include_directories(${OpenCV_INCLUDE_DIRS})

add_executable(imageBasics main.cpp)
#链接OpenCV库
target_link_libraries( imageBasics ${OpenCV_LIBS})

二、.cpp文件

#include <iostream>
//C++标准库chrono:用于时间日期操作
#include <chrono>
//opencv.hpp里面包含了OpenCV各个模块的头文件
#include <opencv2/opencv.hpp>

using namespace std;

//该程序要从终端中读取图像,因此main形参列表要写明
int main(int argc,char **argv) {

    //cv::Mat是OpenCV中的一个矩阵类型,用于存储图像
    cv::Mat image;
    //cv::imread(指定路径)  从指定路径中读取图像,这里是读取终端中第一个参数所指定路径下的图像
    image = cv::imread(argv[1]);

    //image.data中存储的是Mat类型对象image的首地址,为uchar类型指针。如果读取文件返回指针为空,则文件不存在。
    if (image.data == nullptr){
        cerr << "文件" << argv[1] << "不存在" << endl;
        return 0;
    }

    //输出文件基本信息
    //cols为列,所以.cols是图像的宽度;rows是行,所以.rows是图像的高度
    cout << "图像宽度为" << image.cols << ",图像高度为" << image.rows << endl;
    //imshow(“参数1”,参数2),使用imshow显示图片,参数一为显示出来的图像框的名字,参数2为要显示的图像
    cv::imshow("图像",image);
    //程序暂停,检测到任意按键继续
    cv::waitKey(0);

    //判断图像类型
    //.type()会返回Mat类型对象的图像类型
    //CV_8UC3是彩色图,CV_8UC1是灰度图,如果cout出来会发现他们是不同的数
    if (image.type() == CV_8UC3){
        cout << "图像是彩色图" << endl;
    }
    else if (image.type() == CV_8UC1){
        cout << "图像是灰度图" << endl;
    }
    else {
        cout << "图像不是符合要求" << endl;
        return 0;
    }

    //记录当前时间,存储到time_point类型变量t1中
    chrono::steady_clock::time_point t1 = chrono::steady_clock::now();
    //遍历像素
    //图像的遍历方式不是唯一的,下面的方式也不是最高效的,但是是最符合对图像的理解的
    //cv::Mat::data提供了图像数据开头的指针,可直接计算相应元素的偏移量,从而直接得到像素的实际内存位置
    //逐行遍历
    for (size_t y = 0; y < image.rows; y++){
        //获取第y行的头指针到row_ptr
        unsigned char *row_ptr = image.ptr<unsigned char>(y);
        //对指定行中元素逐个遍历
        for (size_t x = 0; x < image.cols; x++){
            //将row_ptr指针从行的开头移动到第x个像素处
            //.channel表示Mat类型对象的通道数
            unsigned  char *data_ptr = &row_ptr[x*image.channels()];
            for (int c = 0; c <=image.channels(); c++){
                //data为(x,y)像素第c通道的数值
                unsigned  char data = data_ptr[c];
            }
        }
    }
    //获取当前时间,存储到time_point类型对象中t2中
    chrono::steady_clock::time_point t2 =chrono::steady_clock::now();
    //由t2和t1计算遍历用时,存储到duration类型对象time_used中,精度为double
    chrono::duration <double> time_used = chrono::duration_cast <chrono::duration <double>> (t2 - t1);
    //duration类型对象需要调用.count()函数才能用cout输出
    cout << "图像遍历用时"  << time_used.count() << "秒" << endl;

    //采用.()clone对cv::Mat类型数据进行拷贝
    cv::Mat image_clone = image.clone();
    //image_another(cv::Rect(x,y,width,height))图像中以(x,y)元素为起点,向右取宽度为width,向下取高度为height的图像矩阵块
    //.setTo(value)设置值为value
    image_clone(cv::Rect(100,100,100,100)).setTo(255);
    cv::imshow("clone后原始图像",image);
    cv::imshow("clone后clone图像",image_clone);
    cv::waitKey(0);

    //对于cv::Mat类型数据,直接赋值并不会拷贝数据
    cv::Mat image_another = image;
    //你会发现对image_another进行操作,image也会跟着变
    image_another(cv::Rect(100,100,100,100)).setTo(0);
    //你会发现你修改的是image_another,但是image也发生了和image_another同样的变化
    cv::imshow("直接赋值后原图像",image);
    cv::imshow("直接赋值后赋值图像",image_another);
    cv::waitKey(0);

    //opencv还提供众多操作,需要之后遇到的时候再学习
    //关闭所有由opencv创建的窗口
    cv::destroyAllWindows();
    std::cout << "Hello, World!" << std::endl;
    return 0;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值