Opencv图像数据结构剖析
Opencv加载图像数据后,不管是什么类型的,都会将图像数据转换点阵图放在内存中。存储图像的数据结构中,包含描述图像的宽、高、通道数等信息,最重要的是有一个指针指向一块连续的内存,这块内存放的就是点阵数据,我们在操作数据时候,其实就是对这个点阵做各种运算。
- 数据结构的定义
Opencv1中,图像用IplImage结构存储,这个结构还是比较简单清晰的。
好像是opencv2吧,引入了cvMat这个结构描述数据,这玩意感觉是个过渡,没用过。后来就cv::Mat了。
到opencv4的时候,之前的数据结构封了,头文件夹里也只剩opencv2,opencv这个文件夹都没了。非要用之前的结构,需要包含个"opencv2/core/core_c.h"。而且IplImage result=mat这种直转的方法也不行了。。。Opencv3的时候用IplImage还挺方便,但是使用cvSaveImage
存图时候直接崩溃。
cv::Mat这玩意吧,封装了很多东西,对于图像数据指针,可以自动释放内存,传递参数啥的可以值传递,它内部自己搞定复制,指向相同数据指针。
它的数据结构里有个data就是数据指针了。
- 内存中的排列
比如一个宽和高都是4像素的图像。
在内存中就是这样连续排列的。
图像涉及到深度和通道数的概念。
一般情况下,我们接触的jpg\bmp\png都是8位深度的图像。也就是说一个位置占一个字节,数据范围就是0~255。
位数比较深的图像一般就是tif,比如16位深度的图像,这样一个位置就占用两个字节,数据范围就是0 ~65535。
对于一个灰度图像,每个像素就用0~255的灰度表示,这种就叫做单通道。
我们常用的彩色图像需要用RGB三种颜色组合,所以每个像素需要三个字节表示,也就是三通道图像。所以我们在画图板、photoshop等工具取图像点颜色时候,就会看到比如红色表示为:255,0,0。
像png这种图,包含一个透明通道,所以就是四通道图像ARGB。A通道这个位置用0~255表示这个像素点的透明度。
所以在内存中,不同类型的图像数据内容就是每个位置点存的数据类型和个数不同,也就是说每个位置占用的内存大小不同。
- 数据操作
我们用这样一个rgb图,通过数据指针方式演示下点阵数据怎么玩。
- 三通道操作
首先简单一点我们把这个图上半部分400行像素全部变成黄色。
这是个8位3通道图像,宽度700,所以每个数据都是uchar一个字节,每个像素占用3个数据,所以图像每行就占用了1*3*700=2100个字节(对应代码中的int widthstep = mat.cols * 3;)。操作数据时,我们就按行移动指针,然后在每个像素位置将它所用的三个字节设置为黄色(每个像素内存中时BGR按位置排列)。
代码及效果如下:
然后稍微复杂一些,我们查找下红色的像素点,将它变成黄色。
这里就是需要遍历到每个像素位置,然后判断RGB值为红色,然后再填充就行了。
代码及示例效果如下:
- 单通道操作
我们把图像中间的300到500行全部变成黑色的。
imread默认会把图像变成3通道所以我们传入参数cv::IMREAD_GRAYSCALE,将图像加载为单通道的灰度图。
8位单通道灰度图处理起来就非常简单,每个像素点一个字节,直接偏移访问就行。而且咱们这里是整行变色,所以访问到一行的起点,然后memset直接把一行700个字节全部设置为黑色就行了。
代码及效果如下:
- 其他类型
对于数据点访问,可以用mat提供的方法,比如访问100行200列位置的数据:
uchar dat = mat.at<uchar>(100, 200);
这种方法感觉就是太慢了,没有指针来的快。
非单通道的数据我们只需要变数据类型来访问,比如uchar是1个字节,对于16位图像,我们转换下指针进行访问就行:
弄懂指针的原理这些其实都是挺随意的。
Opencv图像数据结构剖析相关推荐
- 虹软人脸识别3.0 - 图像数据结构介绍(C++)
从虹软开放了2.0版本SDK以来,由于具有免费.离线使用的特点,我们公司在人脸识别门禁应用中使用了虹软SDK,识别效果还不错,因此比较关注虹软SDK的官方动态.近期上线了ArcFace 3.0 SDK ...
- OpenCV中的三种图像数据结构CvMat, IplImage和Mat(二)IplImage
本文为原创,若有错误欢迎批评指正! 一. IplImage结构体构成 IplImage比CvMat要复杂一些,结构体组成如下: typedef struct _IplImage { int nSize ...
- OPENCV中图像数据结构及其转化
OPENCV中图像数据结构及其转化 1. IplImage 它是openCV库中表示图像的结构体. 初始化: cvLoadImage(),cvCreateImage() 访问元素:[行指针] b = ...
- OpenCV 图像加载和显示
OpenCV 图像加载和显示 OpenCV 图像加载和显示 加载图像(使用cv :: imread) 创建一个名为OpenCV的窗口(使用cv :: namedWindow) 在OpenCV窗口中显示 ...
- OpenCV图像金字塔:高斯金字塔、拉普拉斯金字塔总结
我们经常会将某种尺寸的图像转换为其他尺寸的图像,如果放大或者缩小图片的尺寸,笼统来说的话,可以使用OpenCV为我们提供的如下两种方式: <1> resize函数.这是最直接的方式, &l ...
- 【OpenCV新手教程之十三】OpenCV图像金字塔:高斯金字塔、拉普拉斯金字塔与图片尺寸缩放...
本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接: http://blog.csdn.net/poem_qianmo/article/details/26157633 作者:毛星云(浅墨) ...
- 【OpenCV入门教程之十三】OpenCV图像金字塔:高斯金字塔、拉普拉斯金字塔与图片尺寸缩放
本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接: http://blog.csdn.net/poem_qianmo/article/details/26157633 作者:毛星云(浅墨) ...
- python opencv图像二值化函数_python opencv 二值化 计算白色像素点的实例
python opencv 二值化 计算白色像素点的实例 贴部分代码 #! /usr/bin/env python # -*- coding: utf-8 -*- import cv2 import ...
- OpenCV实战(2)——OpenCV核心数据结构
OpenCV实战(2)--OpenCV核心数据结构 0. 前言 1. cv::Mat 数据结构 1.1 cv::Mat 简介 1.2 cv::Mat 属性 1.3 完整代码示例 2. 探索 cv::M ...
- GCC编译器与OpenCV图像编程
GCC编译器与OpenCV图像编程 一.可执行程序的组装过程 (一)用 gcc 生成 .a 静态库和 .so 动态库 1.编辑得到举例的程序:hello.h.hello.c和main.c 2.将hel ...
最新文章
- 软件测试培训需要学习什么
- vs2019 MFC 中 cannot open include file 'afxres.h' 问题解决方法
- gtk移植到嵌入式_物联网时代的盛行,应届毕业生是学嵌入式好呢,还是安卓或ios呢?...
- 中国工科计算机专业,中国最受欢迎的4个工科专业,第1名有些意外,第3名副其实...
- oracle查看context,oracle context(上下文)
- c++的输入流基础知识
- windows下安装php5.5的redis扩展
- 手写vue---部分实现
- linux 进程的操作,linux进程操作命令
- Java 下的函数对象
- 工程电磁场matlab仿真,带电粒子在电磁场中运动的MATLAB仿真.doc
- qq连连看java版_java仿QQ连连看游戏
- Windows XP 按权限设置共享
- 悉尼大学高级计算机专业世界排名,悉尼大学专业排名一览及最强专业推荐(QS世界大学排名)...
- sre_constants.error: unbalanced parenthesis
- 《算法技术手册》一1.3.5 融会贯通
- 树的搜索问题1(深度优先、广度优先,爬山法和best-first)
- 使用Eclipse把java文件打包成jar
- linux中route命令的用法
- 2020身高体重标准表儿童_儿童0一18岁青少年身高体重标准表-2020年儿童身高体重表图(中国标准版)下载最新比例表-西西软件下载...
热门文章
- Android四大组件每个组件的作用?它们都可以开启多进程吗?
- thinkcmf安装教程与目录结构详解 快速上手版
- mysql数据备份3种方案
- ADSL路由切换IP
- python判断汉字偏胖_写了2年python,知道 if __name__ == '__main__' 什么意思吗?
- 深圳瑞光康泰RBP-9000C血压仪对接
- C#解析HL7协议数据2.X
- 计算机应用与篮球有关的文章,浅析计算机技术应用对高校篮球教学的作用与影响...
- PHP闭包中使用use关键字
- PHP判断请求来自哪个操作系统