OpenCV基础篇之像素访问
2014-10-12 21:31
423 查看
程序及分析
/* * FileName : get_pixels.cpp * Author : xiahouzuoxin @163.com * Version : v1.0 * Date : Sun 01 Jun 2014 06:40:54 PM CST * Brief : * * Copyright (C) MICL,USTB */ #include <cv.h> #include <highgui.h> using namespace std; using namespace cv; int main(int argc, char *argv[]) { if (argc < 2) { cout << "Usage: ./get_pixels [imag name]" << endl; return -1; } Mat img; img = imread(argv[1], 1); /* * Reverse pixels */ Mat out1 = img.clone(); // change dst will not affect img long n_rows = out1.rows; long n_cols = out1.cols * out1.channels(); /* * Row pointer */ uchar *p; for (long i=0; i<n_rows; i++) { p = out1.ptr<uchar>(i); for (long j=0; j<n_cols; j++) { p[j] = 255 - p[j]; } } /* * Element pointer */ Mat out2; out2.create(img.size(), img.type()); // reserve size and type but alloc new space n_rows = out2.rows; n_cols = out2.cols * out2.channels(); p = out2.data; double c = 0.5; double b = 30; for (long i=0; i<n_rows*n_cols; i++) { *(p+i) = (uchar)(255 * 0.5 * ((double)(img.data[i]) / 255) + b); } /* * Display */ namedWindow("src_image", b42f CV_WINDOW_NORMAL); imshow("src_image", img); namedWindow("reverse_image", CV_WINDOW_NORMAL); imshow("reverse_image", out1); namedWindow("mici_image", CV_WINDOW_NORMAL); imshow("mici_image", out2); waitKey(0); return 0; }
基于元素指针的像素访问:根据Mat的数据结构,按理我们可以通过Mat.data访问像素数据的指针,再根据指针访问到像素数据,这是最直接的方法,一般图片数据在内存中都是连续存储(一般应该使用is_continues()进行判断,注意上面程序中没有,因为大部分情况是连续存储的,所以没有考虑),这种访问像素方式的一般格式是:
uchar *p; // 定义一个像素索引指针 p = image.data; // image为Mat对象,将对象的数据指针赋值给p for (long i=0; i < image.rows*image.cols*image.channels(); i++) { *p++ = ..; // 通过索引指针操作数据 }
上面程序通过元素指针的方法给出了一个幂次变换的例子:
*(p+i) = (uchar)(255 * 0.5 * ((double)(img.data[i]) / 255) + b);
幂次变换是一种很好用的图像增强的方法,我的Github上还有一个Matlab写的用幂次变换处理外出爬山风景照片的例子(https://github.com/xiahouzuoxin/zx_photo)
基于行指针的访问:OpenCV中定义了一个ptr方法,是一个模板:
// returns pointer to the matrix element // idx – rows,you should use @isContinues() before decided it template<int n> uchar* ptr(const Vec<int, n>& idx);
通过ptr(i)直接获得Mat对象的第i行的指针,跟二维数组的行指针有些类似,继而可以通过ptr(i)[j]得到第i行第j列的像素值。
上面程序给出了使用行指针进行图像反转的例子。
请注意一下其它的函数:img.clone()之前已经讲过——除了拷贝Mat数据结构的头和数据指针,连数据也一块拷贝,并将数据指针指向新拷贝的数据。
效果
左边是元素图片,中间是经过图片反转之后的图片,右边是使用幂次变换增强后的图片。
相关文章推荐