利用OpenCV处理图像

news/2024/7/21 7:12:38 标签: opencv, 计算机视觉, 图像处理

OpenCV是非常流行的图像处理库,下面介绍一下其对图像的基本操作。

1. 安装与环境

安装还有点儿复杂的,但百度几篇博客基本能解决,这里就不多说了。

安装好后,要在工程中使用OpenCV的头文件和库,需要在CMakeLists.txt中指定:

find_package(OpenCV 4.4)
MESSAGE("OPENCV VERSION: ${OpenCV_VERSION}")
include_directories(${OpenCV_INCLUDE_DIRS})
target_link_libraries(opencv_demo ${OpenCV_LIBS})

2. Demo讲解

2.1 简单读取+展示

  2 #include <opencv2/opencv.hpp>
  3 #include <string>
  4 
  5 using namespace std;
  6 
  7 int main(int argc, char **argv) {
  8     string image_path = "./3.png";
  9     cv::Mat cv_image = cv::imread(image_path, -1);
 10     cv::imshow("hello image", cv_image);
 11     cout << "channel: " << cv_image.channels() << endl;
 12     cout << "row: " << cv_image.rows << endl;
 13     cout << "col: " << cv_image.cols << endl;
 14     cv::waitKey(0);
 15     return 0;
 16 }

1. cv::Mat

cv::Mat是OpenCV提供的用于存储图像的结构,本质上是一个大的二维数组。可以直接在程序中利用[][]访问数组中的元素。

2. cv::imread

cv::imread是读取图像的接口,用于将指定路径的图片读入cv::Mat中。第一个参数就是图片的路径,主流格式都是支持的。第二个参数是一个flag,用于表示读入的方式:

flag=-1:按照原始图像的信息读入

flag=0: 按照灰度图读入

flag=1: 按照彩色图读入(前提是原始图片是彩色的)

3. cv::imshow

cv::imshow用于图片的展示,第一个参数是图片的名字,第二个是存储图片的cv::Mat结构。

通过cv::Mat,可以直接打印出

4. 像素及通道信息

程序除了展示了图片外,还打印了其像素和通道信息:

channel: 4
row: 1080
col: 1920

这些信息是和读入的图片相关的,不同的图片,信息也不一定相同。以这个图片为例,它的像素点有1080行,1920列,所以我们称这个图片的分辨率是1080*1920;通道数为4,是个彩色图片。

    单通道:也就是通常所说的灰度图,每个像素点只有一个值表示,如果图像的深度是4-(256 = 2*2*2*2) 为2^4(下同),那么他的像素取值范围是:0(黑)~255(白),并且仅用一个数字表示该点的像素值;

    三通道:也就是通过见到的彩色图,每个像素点有三个值表示,如果图像深度是4-(256 = 2*2*2*2),那么他的像素值有红(0~255)、绿(0~255)、蓝(0~255)叠加表示,色彩更加艳丽,每一个像素值为三个数字(a,b,c),分别代表了三原色的一种;
    四通道:也就是在三通道图像基础上加上透明程度,Alpha色彩空间,如果图像深度是4-(256 = 2*2*2*2),那么0是完全透明,255是完全不透明;
 

2.2 图片的缩放

上面已经说过,demo中的图片是1080*1920的,下面我们用OpenCV提供的接口将其缩小为原来的1/2,再放大到原来的4/3。

  1 
  2 #include <opencv2/opencv.hpp>
  3 #include <string>
  4 
  5 using namespace std;
  6 
  7 int main(int argc, char **argv) {
  8     string image_path = "./3.png";
  9     cv::Mat origin_image = cv::imread(image_path, -1);
 10     cv::imshow("origin image", origin_image);
 11 
 12     cv::Mat down_image;
 13     auto down_cols = round(origin_image.cols*0.5);
 14     auto down_rows = round(origin_image.rows*0.5);
 15     cv::resize(origin_image, down_image,
 16         cv::Size(down_cols, down_rows), 0, 0, cv::INTER_NEAREST);
 17     cv::imshow("down image", down_image);
 18 
 19     cv::Mat up_image;
 20     auto up_cols = round(origin_image.cols*4/3);
 21     auto up_rows = round(origin_image.rows*4/3);
 22     cv::resize(origin_image, up_image,
 23         cv::Size(up_cols, up_rows), 0, 0, cv::INTER_NEAREST);
 24     cv::imshow("up image", up_image);
 25 
 26     cv::waitKey(0);
 27     return 0;
 28 }

主要就是调用了cv::resize接口,然后通过cv::Size指定目标图片的大小即可,非常简单。

最后的参数是插值的方式

// 在opencv中主要有五种常用的插值方式
1. INTER_LINEAR     双线性插值
2. INTER_NEAREST    最邻近插值
3. INTER_CUBIC        双三次样条插值
4. INTER_AREA        邻域像素再取样
5. INTER_LANCZOS4    8X8领域兰索斯插值

2.3 图片裁剪

  2 #include <opencv2/opencv.hpp>
  3 #include <string>
  4 
  5 using namespace std;
  6 
  7 int main(int argc, char **argv) {
  8     string image_path = "./3.png";
  9     cv::Mat origin_image = cv::imread(image_path, -1);
 10     cv::imshow("origin image", origin_image);
 11 
 12     cv::Mat cropped_image = origin_image(cv::Range(80,280), cv::Range(150,330));
 13     cv::imshow("cropped image", cropped_image);
 14 
 15     cv::waitKey(0);
 16     return 0;
 17 }

这个代码也很容易理解,就不解释了。

到目前为止,遇到的接口都很友好,其实以后想要用哪种接口,直接百度一下即可,接口众多,没必要死记硬背。


http://www.niftyadmin.cn/n/374617.html

相关文章

Java并发编程实践

Java并发编程实践 一、简介1 并发编程的概念与特点2 进程与线程基本概念3 Java线程模型4 线程状态的转换及线程调度模型 二、线程安全性1 线程安全性的定义和实现方式2 synchronized实现线程安全性3 volatile修饰符实现线程安全性4 原子类实现线程安全性 三、Java并发包中的工具…

Socket(六)

文章目录 1. 构造服务器Socket2. 构造但不绑定端口3. 获得服务器Socket的有关信息4. Socket选项5. SO_TIMEOUT6. SO_REUSEADDR7. SO_RCVBUF8. 服务类型 1. 构造服务器Socket 有四个公共的ServerSocket构造函数 public ServerSocket(int port) throws BindException, IOExcept…

NetApp ONTAP Select 混合云存储解决方案

NetApp ONTAP Select 集敏捷性与经验证的数据管理功能于一体。 为什么选择 ONTAP Select 来实施混合云&#xff1f; -强大而敏捷的存储 既具备 ONTAP 软件的强大功能&#xff0c;也能够灵活地部署在远程办公室/后台位置以及数据中心外部的专用边缘环境中的商用硬件上。ONTAP …

CodeForces..李华和迷宫.[简单].[找规律]

题目描述&#xff1a; 题目解读&#xff1a; 存在矩阵迷宫nm&#xff0c;&#xff08;r&#xff0c;c&#xff09;表示从顶部开始的第r行和左起第c列。 如果两单元格共享一个边&#xff0c;则是相邻的。路径是相邻空单元格的序列。 每个单元格初始状态都为空。对于从&#x…

delmia机器人建模与装配

1 可以用catia中的模型或其他三维建模软件中的模型转化为step格式即可 2 在demlia中打开 3 打开单个零件保存为cgr格式 对机械臂所有零件都做同样的转化 4 新建装配设计&#xff0c;并导入带有坐标的零件 将转化后的零件都选中导入即是装配好的 5 将模式修改为device buildin…

静态链接库顺序问题

前言 最近遇到了一个非常奇怪的问题&#xff0c;编译时竟因为链接库的顺序不同&#xff0c;就有完全不同的结果。代码非常简单如下所示&#xff1a; #include "muduo/net/EventLoop.h"int main() {muduo::net::EventLoop loop1;muduo::net::EventLoop loop2;return…

用一杯星巴克的钱,训练自己私有化的ChatGPT

点击蓝字 关注我们 文章摘要&#xff1a;用一杯星巴克的钱&#xff0c;自己动手2小时的时间&#xff0c;就可以拥有自己训练的开源大模型&#xff0c;并可以根据不同的训练数据方向加强各种不同的技能&#xff0c;医疗、编程、炒股、恋爱&#xff0c;让你的大模型更“懂”你….…

ChatGPT50点思考

ChatGPT50点思考 GPT-4的发布还没有确定&#xff0c;但据传其能力可能包括图表和代码等方面的增强。视频生成可能会稍有困难&#xff0c;但对于图片生成和多模态的能力应该不会有太大问题。后派可能更加重视AI安全问题&#xff0c;并将其放在更高的优先级。如果AI的安全性无法…