在对图像进行整张遍历时,用指针会相对高效点。
opencv中如何获取图指针呢?可以用ptr函数来获取第j行首地址。
ptr函数是Mat类中的一个成员函数,用于获取第几行首地址
1 2 3 4 5 6 7 8 |
template<typename _Tp> _Tp* ptr(int i0=0); template<typename _Tp> inline _Tp* Mat::ptr(int y) { CV_DbgAssert( y == 0 || (data && dims >= 1 && (unsigned)y < (unsigned)size.p[0]) ); return (_Tp*)(data + step.p[0] * y); } |
以下是Opencv使用指针遍历图像提高图像亮度的一个例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
void addContrast(Mat& image,int addval) { int nr = image.rows; //行数 int nc = image.cols * image.channels(); if (image.isContinuous()) { //判断在内存中是否连续 nc = nc * nr; nr = 1; } for (int j = 0; j < nr; j++) { uchar* data = image.ptr<uchar>(j); for (int i = 0; i < nc; i++) { if (data[i] + addval > 255) data[i] += addval; else data[i] += addval; } } } void COpencvMFCDlg::OnBnClickedButton24() { Mat image = imread("Lena.bmp", IMREAD_GRAYSCALE); cv::imshow("Image", image); addContrast(image, 40); imshow("提亮后图像", image); } |
指针遍历图像提高图像亮度测试结果

注: if (image.isContinuous()) { //判断在内存中是否连续 nc = nc * nr; nr = 1; }大家可能会看到段有些不明白。这里要讲的是opencv图像在内存中并不一定是连续的,因为有字节对齐的问题,这也是为了提高效率的作法。但有时图像在内存中又刚好是连续的,加了这句判断后,可以将二维for循环转成一维for循环,提高效率。