opencv之访问图像像素的 三种方法
来源:互联网 发布:娱乐圈小鲜肉知乎 编辑:程序博客网 时间:2024/05/17 22:01
opencv之访问图像像素
访问像素的三种方法
①指针访问:最快
②迭代器iterator:较慢,非常安全,指针访问可能出现越界问题
③动态地址计算:更慢,通过at()实现。适用于访问具体某个第i行,j列的像素,而不适用遍历像素
Mat在内存中存储形式
灰度图的存储形式
RGB的存储形式
一般情况下,Mat是连续存储的,按行连接。可以通过isContinuous()函数,判断矩阵是否连续存储,若连续返回true。
访问像素的三种方法
1.指针访问
void VisitImgByPointer(Mat &inputImg, Mat &dstImg){ dstImg = inputImg.clone(); int rows = dstImg.rows; int cols = dstImg.cols * dstImg.channels(); for(int i = 0; i < rows; i++) { uchar* data = dstImg.ptr<uchar>(i); for(int j = 0; j < cols; j++) { data[j] = 0; //处理每一个像素 //add code } } }
当Mat按行连续存储时,可以用指针直接访问所有数据。
void VisitContinueImgByPointer(Mat &inputImg, Mat &dstImg){ dstImg = inputImg.clone(); int rows = dstImg.rows; int cols = dstImg.cols; int channels = dstImg.channels(); if(dstImg.isContinuous()) { cols *= rows; rows = 1; //cout << "is continuous " << endl; } for(int i = 0; i < rows; i++) { uchar* data = dstImg.ptr<uchar>(i); for(int j = 0; j < cols * channels; j++) { data[j] = 155; //处理每一个像素 //add code } } //若存储连续,等效于以下代码 //uchar* data = dstImg.data; //for(int i = 0; i < cols * rows * channels; i++) // data[i] = 155; //处理每一个像素}2.迭代器访问
void VisitImgByIterator(Mat &inputImg, Mat &dstImg){ dstImg = inputImg.clone(); const int channels = dstImg.channels(); switch(channels) { case 1: { Mat_<uchar>::iterator it= dstImg.begin<uchar>(); Mat_<uchar>::iterator itend= dstImg.end<uchar>(); for ( ; it!= itend; it++) //处理每一个像素 { *it = 150; } break; } case 3: { Mat_<Vec3b>::iterator it3= dstImg.begin<Vec3b>(); Mat_<Vec3b>::iterator itend3= dstImg.end<Vec3b>(); for ( ; it3!= itend3; it3++) //处理每一个像素 { (*it3)[0]= 255; (*it3)[1]= 0; (*it3)[2]= 0; } break; } }}
3.动态地址访问
void VisitImgByAt(Mat &inputImg, Mat &dstImg){ dstImg = inputImg.clone(); int rows = dstImg.rows; int cols = dstImg.cols; int channels = dstImg.channels(); switch(channels) { case 1: { for(int i = 0; i < rows; i++) for(int j = 0; j < cols; j++) dstImg.at<uchar>(i,j) = 150; break; } case 3: { for(int i = 0; i < rows; i++) for(int j = 0; j < cols; j++) { dstImg.at<Vec3b>(i,j)[0] = 0; dstImg.at<Vec3b>(i,j)[1] = 0; dstImg.at<Vec3b>(i,j)[2] = 255; } break; } }}
4. 测试代码
#include <iostream>#include <opencv2/opencv.hpp> using namespace cv;using namespace std;void VisitImgByPointer(Mat &inputImg, Mat &dstImg);void VisitContinueImgByPointer(Mat &inputImg, Mat &dstImg);void VisitImgByIterator(Mat &inputImg, Mat &dstImg);void VisitImgByAt(Mat &inputImg, Mat &dstImg);int main(){ Mat srcImg = imread("pig.png"), dstImg; Mat grayImg; cvtColor(srcImg, grayImg, CV_BGR2GRAY); //VisitImgByPointer(srcImg,dstImg); //VisitContinueImgByPointer(grayImg,dstImg); //VisitImgByIterator(srcImg,dstImg); //VisitImgByIterator(grayImg,dstImg); //VisitImgByAt(srcImg,dstImg); VisitImgByAt(grayImg,dstImg); //imshow("原始图", srcImg); //imshow("灰度图", grayImg); imshow("生成图", dstImg); waitKey(0); return 0;}void VisitImgByPointer(Mat &inputImg, Mat &dstImg){ dstImg = inputImg.clone(); int rows = dstImg.rows; int cols = dstImg.cols * dstImg.channels(); for(int i = 0; i < rows; i++) { uchar* data = dstImg.ptr<uchar>(i); for(int j = 0; j < cols; j++) { data[j] = 0; //处理每一个像素 //add code } } }void VisitContinueImgByPointer(Mat &inputImg, Mat &dstImg){ dstImg = inputImg.clone(); int rows = dstImg.rows; int cols = dstImg.cols; int channels = dstImg.channels(); if(dstImg.isContinuous()) { cols *= rows; rows = 1; //cout << "is continuous " << endl; } for(int i = 0; i < rows; i++) { uchar* data = dstImg.ptr<uchar>(i); for(int j = 0; j < cols * channels; j++) { data[j] = 155; //处理每一个像素 //add code } } //若存储连续,等效于一下代码 //uchar* data = dstImg.data; //for(int i = 0; i < cols * rows * channels; i++) // data[i] = 155; //处理每一个像素}void VisitImgByIterator(Mat &inputImg, Mat &dstImg){ dstImg = inputImg.clone(); const int channels = dstImg.channels(); switch(channels) { case 1: { Mat_<uchar>::iterator it= dstImg.begin<uchar>(); Mat_<uchar>::iterator itend= dstImg.end<uchar>(); for ( ; it!= itend; it++) //处理每一个像素 { *it = 150; } break; } case 3: { Mat_<Vec3b>::iterator it3= dstImg.begin<Vec3b>(); Mat_<Vec3b>::iterator itend3= dstImg.end<Vec3b>(); for ( ; it3!= itend3; it3++) //处理每一个像素 { (*it3)[0]= 255; (*it3)[1]= 0; (*it3)[2]= 0; } break; } }}void VisitImgByAt(Mat &inputImg, Mat &dstImg){ dstImg = inputImg.clone(); int rows = dstImg.rows; int cols = dstImg.cols; int channels = dstImg.channels(); switch(channels) { case 1: { for(int i = 0; i < rows; i++) for(int j = 0; j < cols; j++) dstImg.at<uchar>(i,j) = 150; break; } case 3: { for(int i = 0; i < rows; i++) for(int j = 0; j < cols; j++) { dstImg.at<Vec3b>(i,j)[0] = 0; dstImg.at<Vec3b>(i,j)[1] = 0; dstImg.at<Vec3b>(i,j)[2] = 255; } break; } }}
原文链接:http://www.cnblogs.com/kuotian/p/6389260.html?utm_source=itdadao&utm_medium=referral
阅读全文
0 0
- opencv之访问图像像素的 三种方法
- Opencv访问图像像素的三种方法
- opencv:访问图像中像素的三类方法
- opencv访问像素的三种方法
- opencv学习三种常用方法访问操作图像像素
- OpenCV访问图像像素的方法
- openCV中访问图像像素的两种方法
- Opencv3编程入门学习笔记(三)之访问图像像素的三种方法
- OPENCV2 访问图像像素值的三种方法
- OPENCV2 访问图像像素值的三种方法
- openCV学习笔记-三种访问像素的方法
- OpenCV学习笔记(七):访问图像中像素的三类方法
- python OpenCV 图像像素访问 (三)
- opencv里常用的访问图像像素数据方法
- opencv访问(Mat)图像的像素方法汇总
- opencv访问图像像素
- opencv访问图像像素
- Opencv访问图像像素
- JAVA学习篇--Servlet详解
- Oracle Data Guard(数据卫士)简介 11gR2
- Numpy--存取数组
- C++的拷贝构造函数的四种调用
- AE,多点转线、面
- opencv之访问图像像素的 三种方法
- PAT乙级 1035. 插入与归并(25)
- CPL RPL DPL 一致代码段 非一致代码段 总结
- 代码整洁之道阅读笔记
- MOOC清华《程序设计基础》第4章:整理扑克牌(插入排序精简版)
- 动脉硬化知识系列:开篇和生化检测科普1
- ORA-00600: 内部错误代码, 参数: [rwoirw: check ret val], [], [], [], [], [], [], [], [], [], [], []
- NET下的流程图开发包介绍
- 什么是死锁?