当前位置: 首页 > news >正文

【和春笋一起学C++】OpenCV中数组和指针运用实例

前言:前面学习了数组和指针在C++中的处理原理,本文通过自己编写一个图像处理的函数实例来加深对数组和指针的理解。为什么是图像处理呢,因为图像数据是一个二维矩阵,相当于一个二维数组,前面学习了一维数组,现在可以看看指针是怎么来处理二维数组的。

目录

遍历OpenCV中图像像素方法一

遍历OpenCV中图像像素方法二

总结


正文:我们首先使用opencv图像处理库读入一张图像,然后对图像进行二值化(opencv库中已经集成了此功能,此处自己编写仅仅为了巩固指针和数组的知识)。

遍历OpenCV中图像像素方法一

代码如下:

#include <iostream>
#include <cstring>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;int main()
{Mat srcImage = imread("test.jpg");Mat srcGray;cvtColor(srcImage, srcGray, COLOR_BGR2GRAY);Mat outputImage = srcGray.clone();int rows = outputImage.rows;int cols = outputImage.cols*outputImage.channels();int threshold = 50;for (int i = 0; i < rows; i++){uchar* data = outputImage.ptr<uchar>(i);///获取第i行的首地址for (int j = 0; j < cols; j++){if (data[j] < threshold){data[j] = 255;}else{data[j] = 0;}}}imshow("src", srcImage);imshow("binary", outputImage);waitKey();return 0;
}

该方法中最重要的是这条语句:uchar* data = outputImage.ptr<uchar>(i);Mat类中的ptr函数返回的是某一行的首地址,ptr是一个模板函数,代码中它返回的是第i行的首地址。

第一个循环体内获取每行的首地址,第二个循环体内获取每行的每个像素值,并做阈值划分。前面文章《使用new创建动态数组》讲过,访问数组中的元素既可以用指针访问,也可以用数组的方括号表示法来访问,此处用的是方括号表示法,data[j]代表的是第i行中的第(j+1)个像素,通过双层循环对图像中每一行的每个像素做阈值划分,就完成了图像的二值化。

也可以通过指针的方式来访问图像中的每个像素,将上面代码中的循环体换成以下代码,运行的结果是一样的。

for (int i = 0; i < rows; i++){uchar* data = outputImage.ptr<uchar>(i);///获取第i行的首地址for (int j = 0; j < cols; j++){if ((*(data+j)) < threshold){*(data + j) = 255;}else{*(data + j) = 0;}}}

遍历OpenCV中图像像素方法二

方法一中通过获取每行的首地址来访问每行中的每个像素。也可以直接通过二维数组的整个数组的首地址来访问每个像素,代码如下:

#include <iostream>
#include <cstring>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;int main()
{Mat srcImage = imread("test.jpg");Mat srcGray;cvtColor(srcImage, srcGray, COLOR_BGR2GRAY);Mat outputImage = srcGray.clone();int rows = outputImage.rows;int cols = outputImage.cols*outputImage.channels();int threshold = 50;uchar* data = outputImage.data;for (int i = 0; i < rows; i++){for (int j = 0; j < cols; j++){if (data[i*cols+j] < threshold){data[i*cols + j] = 255;}else{data[i*cols + j] = 0;}}}imshow("src", srcImage);imshow("binary", outputImage);waitKey();return 0;
}

方法二中最重要的是这条语句:uchar* data = outputImage.data; Mat类中的data指针指向的就是图像数据二维数组的首地址,该方法用的是数组的方括号表示法来访问每个像素。同理,循环体中也可以换成指针的方式来访问每个像素。循环体中的代码换成指针的方式如下:

for (int i = 0; i < rows; i++){for (int j = 0; j < cols; j++){if (*(data+i*cols + j) < threshold){*(data + i * cols + j) = 255;}else{*(data + i * cols + j) = 0;}}}

总结

opencv中遍历图像像素的方法有十几种,本文通过4种遍历图像像素的方式编写了一个简单的图像二值化函数,既巩固了指针和数组的知识,又掌握了遍历opencv中图像像素的方法。

 

http://www.lryc.cn/news/495936.html

相关文章:

  • Maya 中创建游戏角色的头发,并将其导出到 Unreal Engine 5
  • React 路由(React Router):在 React 应用中管理路由
  • SAP-CPI组件Transformation介绍之Converter
  • Laravel 代理收益排行榜
  • LeetCode hot100面试背诵版(自用)
  • 常见的Web安全漏洞——XSS
  • liteflow 架构详解
  • 国产麒麟操作系统上运行LabVIEW
  • 【C语言】结构体(一)
  • C++《set与map》
  • 深度学习-52-AI应用实战之基于Yolo8的目标检测自动标注
  • 【Elasticsearch】05-DSL查询
  • qml项目创建的区别
  • .NET8/.NETCore 依赖注入:自动注入项目中所有接口和自定义类
  • Flutter:city_pickers省市区三级联动
  • Kafka-Connect自带示例
  • Hbase应用案例 随机号码生成
  • 论文阅读——量子退火Experimental signature of programmable quantum annealing
  • (长期更新)《零基础入门 ArcGIS(ArcMap) 》实验二----网络分析(超超超详细!!!)
  • go语言 Pool实现资源池管理数据库连接资源或其他常用需要共享的资源
  • mysql一个事务最少几次IO操作
  • 运输层总结
  • 【嵌套查询】.NET开源 ORM 框架 SqlSugar 系列
  • React 前端框架1
  • 【真正离线安装】Adobe Flash Player 32.0.0.156 插件离线安装包下载(无需联网安装)
  • 数据采集时,不同地区的动态IP数据质量有什么差异?
  • 【Python爬虫五十个小案例】爬取猫眼电影Top100
  • 等保测评和 ISO27001 都是信息保护,区别是什么?
  • Linux系统编程之进程创建
  • JAVA-IO