2013年3月2日

Opencv2:幾種存取像素的方法

此範例為四種Opencv 2存取像素點的方法,使用灰階的例子顯示。

IDE:  Code::Blocks

Complier:  MinGw

OS:  Windows 7

#include<opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include<iostream>
void grayM1(cv::Mat &image);
void grayM2(cv::Mat &image);
void grayM3(cv::Mat &image);
void grayM4(cv::Mat &image);
int main()
{
    using namespace std;
    cv::Mat image=cv::imread("D:\\img\\lena_std.bmp");
    grayM1(image);  //使用Mat::at Vec3b模板函數
    //grayM2(image);    //使用Mat::ptr Vec3b模板函數
    //grayM3(image);    //使用Mat::at uchar模板函數
    //grayM4(image);    //使用Mat::data 直接存取Mat memory address
    cv::imshow("img",image);
    cv::waitKey(0);
    cv::destroyWindow("img");
    return 0;
}

void grayM1(cv::Mat &image){
    using namespace cv;
    Vec3b s1,s2;
    for(int i=0;i<image.rows;i++){
        for(int j=0;j<image.cols;j++){
            s1=image.at<Vec3b>(i,j);    //可回傳一個Vec3b的三通道向量
            s2.val[0]=s1.val[0]*0.114+s1.val[1]*0.587+s1.val[2]*0.299;
            image.at<Vec3b>(i,j)[0]=s2.val[0];
            image.at<Vec3b>(i,j)[1]=s2.val[0];
            image.at<Vec3b>(i,j)[2]=s2.val[0];
        }
    }
}

void grayM2(cv::Mat &image){
    using namespace cv;
    Vec3b *s1;
    double result=0;
    for(int i=0;i<image.rows;i++){
        s1=image.ptr<Vec3b>(i); //回傳一個指向該列向量開頭的Vec3b型態指標
        for(int j=0;j<image.cols;j++){
            result=s1[j].val[0]*0.114+s1[j].val[1]*0.587+s1[j].val[2]*0.299;    //存取該行之三通道
            s1[j].val[0]=s1[j].val[1]=s1[j].val[2]=result;
        }
    }
}

void grayM3(cv::Mat &image){
    using namespace cv;
    uchar *s1;
    double result=0;
    for(int i=0;i<image.rows;i++){
        s1=image.ptr<uchar>(i); //回傳一個指向該列向量開頭記憶體位址的uchar型態指標
        for(int j=0;j<image.cols;j++){
            result=s1[j*3]*0.114+s1[j*3+1]*0.587+s1[j*3+2]*0.299;   //排列方式為GBR
            s1[j*3]=s1[j*3+1]=s1[j*3+2]=result;
        }
    }
}

void grayM4(cv::Mat &image){
    using namespace cv;
    double result=0;
    for(int i=0;i<image.rows;i++){
        for(int j=0;j<image.cols;j++){ //image.data為指向該矩陣開頭的記憶體位址+行寬度+列高度+(三通道排列順序)
            result=(*(image.data + (image.step[0] * j + image.step[1] * i)))*0.114+
            (*(image.data + (image.step1(0) * j + image.step1(1) * i)+1))*0.587+
            (*(image.data + (image.step1(0) * j + image.step1(1) * i)+2))*0.299;    //使用* 運算子存取
            *(image.data + (image.step1(0) * j + image.step1(1) * i))=
            *(image.data + (image.step1(0) * j + image.step1(1) * i)+1)=
            *(image.data + (image.step1(0) * j + image.step1(1) * i)+2)=result;
        }
    }
}


結果如下圖:


有錯誤麻煩留言告知 謝謝!!

By Victor

沒有留言:

張貼留言