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

it2024-12-09  14

一、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)