歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

OpenCV基礎篇之像素訪問

OpenCV基礎篇之像素訪問

程序及分析

/*
 * 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", 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;
}
 1.
基於元素指針的像素訪問:根據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)

2.
基於行指針的訪問: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列的像素值。

上面程序給出了使用行指針進行圖像反轉的例子。

3.
請注意一下其它的函數:img.clone()之前已經講過——除了拷貝Mat數據結構的頭和數據指針,連數據也一塊拷貝,並將數據指針指向新拷貝的數據。

效果

 

左邊是元素圖片,中間是經過圖片反轉之後的圖片,右邊是使用冪次變換增強後的圖片。

--------------------------------------分割線 --------------------------------------

Ubuntu Linux下安裝OpenCV2.4.1所需包 http://www.linuxidc.com/Linux/2012-08/68184.htm

Ubuntu 12.04 安裝 OpenCV2.4.2 http://www.linuxidc.com/Linux/2012-09/70158.htm

CentOS下OpenCV無法讀取視頻文件 http://www.linuxidc.com/Linux/2011-07/39295.htm

Ubuntu 12.04下安裝OpenCV 2.4.5總結 http://www.linuxidc.com/Linux/2013-06/86704.htm

Ubuntu 10.04中安裝OpenCv2.1九步曲 http://www.linuxidc.com/Linux/2010-09/28678.htm

基於QT和OpenCV的人臉識別系統 http://www.linuxidc.com/Linux/2011-11/47806.htm

--------------------------------------分割線 --------------------------------------

Copyright © Linux教程網 All Rights Reserved