读取图像,LUT以及计算耗时
使用LUT(lookup table)检索表的方法,提高color reduce时对像素读取的速度。
实现对Mat对象中数据的读取,并计算color reduce的速度。
方法一:使用Mat的ptr()遍历行(row),效率较高,使用时需要小心细节
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#include <sstream> using namespace std;
using namespace cv; static void help(){
cout
<< "Author: BJTShang" << endl
<< "2016-12-22, CityU" << endl
<< "Use: " << "./1222_LUP imageName divideWith [G]" << endl
<<endl;
} Mat& ScanImageAndReduceC(Mat& I, const uchar* table);
Mat& ScanImageAndReduceIterator(Mat& I, const uchar* table); int main(int argc, char** argv){
help();
if(argc<){
cout << "Not enough parameters!" << endl;
return -;
} Mat I;
char* imageName = argv[];
if(argc== && !strcmp(argv[],"G")){
I = imread(imageName, CV_LOAD_IMAGE_GRAYSCALE);
}else{
I = imread(imageName, CV_LOAD_IMAGE_COLOR);
} if(!I.data){
cout << "The image" << imageName << " has no data!";
return -;
} int divideWith = ;
stringstream s;
s << argv[];
s >> divideWith;
if(!s || !divideWith){
cout << "Invalid divideWith, input again (positive integer)!" << endl;
return -;
} // use this table to search for (by simple assignment) reduced intensity,
// instead of calculating for each pixel, which is computational high-cost
uchar table[];
for(int i=; i < ; ++i){
table[i] = uchar((i/divideWith)*divideWith);
} int64 t0 = getTickCount();
Mat J = I.clone();
J = ScanImageAndReduceC(J, table);
double t = (double)(getTickCount() - t0)/getTickFrequency();
cout << "Elapse time = " << t* << " ms" <<endl; namedWindow("before", CV_WINDOW_AUTOSIZE);
namedWindow("after color reduce by LUT", CV_WINDOW_AUTOSIZE);
imshow("before", I);
imshow("after color reduce by LUT", J);
waitKey();
return ;
} Mat& ScanImageAndReduceC(Mat& I, const uchar* table){
CV_Assert(I.depth() == CV_8U);
const int channels = I.channels(); int nRows = I.rows;
int nCols = I.cols*channels; if (I.isContinuous()){
nCols *= nRows;
nRows = ;
} uchar* p = NULL;
for(size_t i=; i<nRows; ++i){
p = I.ptr<uchar>(i);
for(size_t j=; j<nCols; ++j){
p[j] = table[p[j]];
}
}
// Mat结构的ptr()方法,返回指向Mat每一行的头元素指针
// Mat结构的data属性,返回指向元素的指针,p++指针自加到下一块元素地址。
// 如果Mat中元素连续,才可以使用*p++取出所有元素值;若Mat中元素不连续,*p++取出第二行开始肯定错误!
// uchar* p = I.data;
// for(size_t i = 0; i < nRows*nCols; ++i){
// *p++ = table[*p];
// }
return I;
}
结果:

如果使用*p++的方法,结果不同:

这种方法,需要自己考虑图像每一行之间的gap,以及元素类型(uchar和float32f的不同)。效率较高,但不小心会出问题。
方法二:通过MatIterator类安全地访问Mat结构
效果相同,但是运行时间会变长几倍(我的电脑上大约是3倍)
Mat& ScanImageAndReduceIterator(Mat& I, const uchar* table){
CV_Assert(I.depth() == CV_8U);
int channels = I.channels();
switch(channels){
case :
{
MatIterator_<uchar> it,end;
for(it = I.begin<uchar>(), end = I.end<uchar>(); it!=end; ++it)
*it = table[*it];
break;
}
case :
{
MatIterator_<Vec3b> it, end;
for(it = I.begin<Vec3b>(), end = I.end<Vec3b>(); it!=end; ++it){
(*it)[] = table[(*it)[]];
(*it)[] = table[(*it)[]];
(*it)[] = table[(*it)[]];
}
break;
}
}
return I;
}
对于3通道彩色图像,需要指定迭代器中元素类型为short vector: <Vec3b>。如果指定为uchar,迭代器器将只会扫描B蓝色通道;当然,这里的情况因为使用了[]操作符访问short vector中的sub colomun, 编译就通不过。。。
方法三:最容易理解,但是最不推荐的是使用Mat的at()方法
Mat& ScanImageAndReduceRandomAccsee(Mat& I, const uchar* table){
CV_Assert(I.depth() == CV_8U);
const int channels = I.channels();
switch(channels){
case :
{
for(int i=; i<I.rows; ++i)
for(int j=; j<I.cols; ++j)
I.at<uchar>(i,j) = table[I.at<uchar>(i,j)];
break;
}
case :
{
Mat_<Vec3b> _I = I; // this was used to check the data (3 channels), as well as to use [] operator to access different channels
for(int i=; i<I.rows; ++i)
for(int j=; j<I.cols; ++j){
_I(i,j)[] = table[_I(i,j)[]]; // equal to _I.at(i,j*3) = table[_I.at(i,j*3)]
_I(i,j)[] = table[_I(i,j)[]]; // equal to _I.at(i,J*3+1) = table[_I.at(i,j*3+1)]
_I(i,j)[] = table[_I(i,j)[]]; // equal to _I.at(i,j*3+2) = table[_I.at(i,j*3+2)]
}
I = _I;
break;
}
}
return I;
}
效率和安全的使用MatIterator类差不多,想访问矩阵中特定位置的元素使用这种方法是比较合适的。
最后,OpenCV封装了LUT的color reduce方法。平常直接使用即可,效率比较高。
Mat lookUpTable(, , CV_8U);
uchar* p = lookUpTable.data;
for(int i=; i<; i++)
p[i] = table[i];
LUT(I,lookUpTable,J);
读取图像,LUT以及计算耗时的更多相关文章
- Exif.js 读取图像的元数据
Exif.js 提供了 JavaScript 读取图像的原始数据的功能扩展,例如:拍照方向.相机设备型号.拍摄时间.ISO 感光度.GPS 地理位置等数据. 注意事项: EXIF 数据主要来自拍摄的照 ...
- GDAL库——读取图像并提取基本信息
GDAL库是一个跨平台的栅格地理数据格式库,包括读取.写入.转换.处理各种栅格数据格式(有些特定的格式对一些操作如写入等不支持).它使用了一个单一的抽象数据模型就支持了大多数的栅格数据.这里有GDAL ...
- 图像相似度计算之哈希值方法OpenCV实现
http://blog.csdn.net/fengbingchun/article/details/42153261 图像相似度计算之哈希值方法OpenCV实现 2014-12-25 21:27 29 ...
- PS图像菜单下计算命令
PS图像菜单下计算命令通过通道的混合模式得到的选区非常精细,从而调色的时候过度非常好.功能十分强大. 下面用计算命令中的"相加"和"减去"模式做实例解析,这 ...
- OpenCV2:第三章 读取图像
一.简介 将图像文件读入内存,可以用cv::imread()函数 二.读取图像 Mat imread(const string& filename,int flags=1); Mat: 如果读 ...
- python3读取图像并可视化的方法(PIL/Pillow、opencv/cv2)
原图: 使用TensorFlow做图像处理的时候,会对图像进行一些可视化的操作.下面,就来列举一些我知道的图像读取并可视化的方法. 1. Pillow模块 1.1 Pillow模块的前生 Pillow ...
- 基于gtk的imshow:用stb_image读取图像并用gtk显示
在前面一篇,已经能够基于gtk读取图像并显示.更前面的一篇:基于GDI的imshow:使用stb_image读取图像并修正绘制,通过stb_image读取图像并通过GDI显示图像,实现了一个imsho ...
- OpenCV读取图像问题:OpenCV(3.4.3) D:\Build\OpenCV\opencv-size.width0 && size.height0 in function 'cvimshow'
版权声明:本文为博主原创文章,转载 请注明出处:https://blog.csdn.net/sc2079/article/details/83280067 - 问题与解决 最近正在学OpenCV,发现 ...
- opencv学习之读取图像-imread函数
序 想要完整全面地学习opencv,仅凭阅读samples的示例源码是不够的.毕竟opencv是一个拥有非常多函数的程序库,所以在每学习一个函数时,芒果觉得有必要记录下来,分享给有需要的同学.于是,就 ...
随机推荐
- 《使用Hibernate开发租房系统》内部测试笔试题
笔试总结 1.在Hibernate中,以下关于主键生成器说法错误的是( C). A.increment可以用于类型为long.short或byte的主键 B.identity用于如SQL Server ...
- [No00008B]远程桌面发送“Ctrl+Alt+Delete”组合键调用任务管理器
向远程桌面发送"Ctrl+Alt+Delete"组合键的两种方法 1.在本地按下Ctrl+Alt+End,可以成功发送"Ctrl+Alt+Delete"组合键! ...
- 安全测试 - 抓包工具BurpSuite
Brup SuiteBurpSuite是用于攻击web应用程序的集成平台.它包含了许多工具,并为这些工具设计了许多接口,以促进加快攻击应用程序的过程.所有的工具都共享一个能处理并显示HTTP消息,持久 ...
- TesseractOCR
简介: OCR(Optical Character Recognition):光学字符识别,是指对图片文件中的文字进行分析识别,获取的过程. Tesseract:开源的OCR识别引擎,初期Tesser ...
- docker 常用命令(*)
查找镜像 https://hub.docker.com/ search --> centos7 一般docker 会有一个基础镜像,中间件镜像,应用镜像,生成一个镜像 docker build ...
- weui 搜索框
点击搜索,会显示关键字取消按钮,输入文字,会在搜索框下,有相应的列表显示. HTML: <!DOCTYPE html> <html> <head> <meta ...
- Dockerfile初探
git上的asp.net samples工程已经写好了docker file,内容是如下 //任何dockersfile都要以FORM开头,约定是用大写. FROM microsoft/aspne ...
- pip安装使用详解(转)
pip类似RedHat里面的yum,安装Python包非常方便.本节详细介绍pip的安装.以及使用方法. 1.pip下载安装 1.1 pip下载 1 # wget "https://py ...
- 【转】OpenGL多线程创建纹理,附加我的测试结果
原文地址 http://www.cnblogs.com/mazhenyu/archive/2010/04/29/1724190.html 关于这个问题以前只知道多个线程不能同时使用一个RC,结果为了能 ...
- $.post 跨域传输数据
使用的是TP框架 前端代码: <!DOCTYPE html><html> <head> <title>这里是前端代码</title> < ...