第5章 Core组件进阶

5.1 访问图像中的像素

5.1.1 图像在内存中的存储方式

1.图像矩阵大小取决于通道数,矩阵中的子列个数与通道数相等。
2.如果内存足够大,可以实现连续存储,有助于提升图像扫描速度,可以用isContinuous()判断矩阵是否连续存储。

5.1.2 颜色空间缩减

1.颜色空间缩减:将现有颜色空间值除以某个输入值,以获得较少的颜色数
2.如,0~9范围的像素值为0,10~19范围的像素值为10等
3.颜色空间缩减算法:(1)遍历图像矩阵的每一个像素(2)对像素应用公式int I=(I/10)*10;
4.打表:

int divideWith = 10;uchar table[256];for (int i = 0; i < 256; i++)table[i] = divideWith * (i / divideWith);

5.1.3 LUT函数:Look up table操作

1.operationsOnArrays:LUT()函数:用于批量进行图像元素查找、扫描与操作图像
2.使用方法:

//首先建立一个mat型用于查表Mat lookUpTable(1, 256, CV_8U);uchar* p = lookUpTable.data;for(int i = 0; i < 256; i++){p[i]= table[i];}//调用函数(I是输入J是输出)for(int i = 0; i < times; ++i){LUT(image, lookUpTable, dstImage);}

5.1.4 计时函数

1.getTickCount()函数:返回CPU自某个事件(如启动电脑)以来走过的时钟周期数
2.getTickFrequency()函数:返回CPU一秒钟所走的时钟周期数。
3.示例:

#include<opencv2/opencv.hpp>
#include<cstdio>
using namespace cv;
using namespace std;int main()
{//记录起始时间double time0 = static_cast<double>(getTickCount()); //进行图像处理操作Mat image = imread("1.jpg");Mat dstImage;blur(image, dstImage, Size(7, 7));imshow("[1]image proc", dstImage);//计算方法运行时间time0 = ((double)getTickCount() - time0) / getTickFrequency();cout << "此方法运行时间为:" << time0 << "秒" << endl;waitKey(0);return 0;
}

5.1.5 访问图像中像素的三类方法

1.指针访问:C操作符[]
2.迭代器iteator
3.动态地址计算

例:将源图像中的颜色数量由256种减少到64种

#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<iostream>
using namespace cv;
using namespace std;void colorReduce(Mat& inputImage, Mat& outputImage, int div);int main()
{//创建原始图并显示Mat srcImage = imread("1.jpg");imshow("原始图像", srcImage);//[2]按原始图像的参数规格来创建效果图Mat dstImage;dstImage.create(srcImage.rows, srcImage.cols, srcImage.type());//效果图的大小、类型与原图片相同//[3]记录起始时间double time0 = static_cast<double>(getTickCount());//[4]调用颜色空间缩减函数colorReduce(srcImage, dstImage, 32);//[5]计算运行时间并输出time0 = ((double)getTickCount() - time0) / getTickFrequency();cout << "此方法运行时间为:" << time0 << "秒" << endl;//[6]显示效果图imshow("效果图", dstImage);waitKey(0);return 0;
}
//【方法一】用指针访问像素
void colorReduce(Mat& inputImage, Mat& outputImage, int div)
{//参数准备outputImage = inputImage.clone();//复制实参到临时变量int rowNumber = outputImage.rows;//行数int colNumber = outputImage.cols*outputImage.channels();//列数*通道数=每一行元素的个数//双重循环,遍历所有的像素值for (int i = 0; i < rowNumber; i++){uchar* data = outputImage.ptr<uchar>(i); //获取第i行的首地址(Mat类的ptr函数可以得到图像任意行的首地址)for (int j = 0; j < colNumber; j++){//处理每个像素data[j] = data[j] / div * div + div / 2;}}
}
//【方法二】用迭代器操作像素
void colorReduce(Mat& inputImage, Mat& outputImage, int div)
{//参数准备outputImage = inputImage.clone();//复制实参到临时变量//获取迭代器Mat_<Vec3b>::iterator it = outputImage.begin<Vec3b>(); //初始位置的迭代器Mat_<Vec3b>::iterator itend = outputImage.end<Vec3b>(); //终止位置的迭代器//存取彩色图像像素for (; it != itend; ++it){//开始处理每个像素(*it)[0] = (*it)[0] / div * div + div / 2;(*it)[1] = (*it)[1] / div * div + div / 2;(*it)[1] = (*it)[1] / div * div + div / 2;}
}
//【方法三】动态地址计算
void colorReduce(Mat& inputImage, Mat& outputImage, int div)
{//参数准备outputImage = inputImage.clone();//复制实参到临时变量int rowNumber = outputImage.rows;//行数int colNumber = outputImage.cols;//列数//存取彩色图像像素for (int i = 0; i < rowNumber; i++){for (int j = 0; j < colNumber; j++){//对于彩色图像,每个像素有三个部分构成,三个8位数组成的向量分别代表三个通道,Vec3b即由三个unisigned char组成的向量,image.at<Vec3b>(i,j)[channel]=value;是为图像image第i行第j列的像素点的channel分量赋值//开始处理每个像素(成员函数at(int y,int x)可以用来存取元素,但是必须在编译期知道图像的数据类型)outputImage.at<Vec3b>(i, j)[0] = outputImage.at<Vec3b>(i, j)[0] / div * div + div / 2; //蓝色通道outputImage.at<Vec3b>(i, j)[1] = outputImage.at<Vec3b>(i, j)[1] / div * div + div / 2; //绿色通道outputImage.at<Vec3b>(i, j)[2] = outputImage.at<Vec3b>(i, j)[2] / div * div + div / 2; //红色通道}}
}

《OpenCV3编程入门》学习笔记5 Core组件进阶(一)访问图像中的像素相关推荐

  1. 原创 OpenCV3编程入门 学习笔记(总)

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/qq_36163358/article/ ...

  2. OpenCV3编程入门 学习笔记(总)

    OpenCV3编程入门 学习笔记 2018.12.12-2018.12.29 此博客为在看过毛星云版<OpenCV3编程入门>后所总结的一本笔记,可供复习使用. 文章目录 OpenCV3编 ...

  3. 《OpenCV3编程入门》学习笔记5 Core组件进阶(四)图像对比度、亮度值调整

    第5章 Core组件进阶 5.4 图像对比度.亮度值调整 5.4.1 理论依据 1.算子:一般图像处理算子都是一个函数,接受一个或多个输入图像,并产生输出图像 2.算子一般形式: 3.点操作(poin ...

  4. Opencv3编程入门学习笔记(五)之通道分离(split)与合并(merge)

    若要对Opencv中(BGR)颜色通道进行单一处理,那必然会涉及到通道分离(split)与合并(merge).那么本篇博客笔者记录了两个方法的使用方法和案例.案例来源于<Opencv3编程入门学 ...

  5. 《OpenCV3编程入门》学习笔记5 Core组件进阶(六)输入输出XML和YAML文件

    第5章 Core组件进阶 5.6 输入输出XML和YAML文件 5.6.1 XML和YAML文件 XML和YAML是使用非常广泛的文件格式,可以利用XML或者YAML式的文件存储和还原各种数据结构,还 ...

  6. 《OpenCV3编程入门》学习笔记5 Core组件进阶(五)离散傅里叶变换(DFT)

    第5章 Core组件进阶 5.5 离散傅里叶变换(Discrete Fourier Transform,DFT) 5.5.1 离散傅里叶变换原理 1.对一张图像使用傅里叶变换就是把它分解成正弦和余弦, ...

  7. 《OpenCV3编程入门》学习笔记5 Core组件进阶(三)分离合并颜色通道

    第5章 Core组件进阶 5.3 分离&合并颜色通道 5.3.1 通道分离:split()函数 1.作用:将一个多通道数组分离成几个单通道数组,公式: 2.原型:(1)void split(c ...

  8. 《OpenCV3编程入门》学习笔记5 Core组件进阶(二) ROI区域图像叠加图像混合

    第5章 Core组件进阶 5.2 ROI区域图像叠加&图像混合 5.2.1 感兴趣区域ROI(region of interest) 1.定义ROI区域两种方法: (1)定义矩形区域Rect: ...

  9. 【OpenCV3编程入门学习笔记】——第1章 邂逅OpenCV

    邂逅OpenCV 文章目录 邂逅OpenCV 前言 1.1 OpenCV周边概念认知 1.1.1 图像处理.计算机视觉与OpenCV 1.1.2 OpenCV概述 1.1.3 起源及发展 1.1.4 ...

最新文章

  1. bug诞生记——信号(signal)处理导致死锁
  2. Docker学习笔记_安装ActiveMQ
  3. 昨日,GitHub宣布收购npm,微软或成最大赢家!
  4. 是什么专业_聚焦专业:什么是好专业?考古专业明年会成为热门吗?
  5. Yii-upload- 用AJAX上传图片
  6. AI基础:数据可视化简易入门(Matplotlib 和 Seaborn)
  7. (转)mybatis常用jdbcType数据类型
  8. OkHttp如何移除User-Agent,Accept-Encoding等框架自动添加的请求头参数
  9. 乐鑫esp8266基于freeRtos实现私有服务器本地远程OTA升级
  10. maven学习(4)
  11. springloaded热加载
  12. angular中的MVVM模式
  13. linux 查找并删除
  14. win2012故障转移mysql集群_在Windows Server 2012 R2中搭建SQL Server 2012故障转移集群
  15. spring定时器的使用
  16. chrome全屏模式书签栏/工具栏消失如何处理
  17. 李宏毅机器学习课程自测练习题
  18. VBS 常用总汇 (http://blog.csdn.net/sgear/article/details/1380223)
  19. 加密芯片十大品牌对比
  20. JPA 中对象 set 属性时自动保存

热门文章

  1. 2022-2028年中国帘子布行业市场研究及前瞻分析报告
  2. 2022-2028年中国TPE手套行业市场全景调查及发展策略分析报告
  3. Docker 入门系列(5)- Docker 端口映射(映射所有IP地址、映射到指定地址和指定端口、映射指定地址任意端口、查看映射端口配置)
  4. pandas dataframe 字符映射为数字
  5. deepstream-开放式实时服务器
  6. 详解PHP实现定时任务的五种方法
  7. C++ 中multiset 的使用
  8. python3x 线程threading的使用
  9. HarmonyOS开发工具DevEcoStudio 的下载以及运行(包含下载开发工具,sdk,模拟机,以及运行第一个应用你好,世界)
  10. python 将一个整数变成2个字节的字符