opencv笔记 3.访问图像元素的四种方法

//访问图像像素,使图像三通道分离
#include<iostream>
#include<cv.hpp>
using namespace cv;
using namespace std;

//声明四种最常用,简单的访问像素的方法
void bluechannel(Mat ROI, Mat outputImage);
void greenchannel(Mat ROI, Mat outputImage);
void redchannel(Mat ROI, Mat outputImage);
void channel(Mat inputImage, Mat outputImage);

int main()
{
    //定义三个Mat变量
    Mat srcimage = imread("1.jpg");
    Mat logo = imread("2.jpg");
    Mat outputImage;
    //namedWindow("混合图", WINDOW_NORMAL);


    //融合图像并显示
    Mat ROI = srcimage(Rect(500, 200, logo.cols, logo.rows));
    addWeighted(logo, 0.8, ROI, 0.4, 0, ROI);
    //上面两行代码可以用下面一行代替
    //addWeighted(logo, 0.2, srcimage(Rect(500, 200, logo.cols, logo.rows)), 0.8, 0, srcimage(Rect(500, 200, logo.cols, logo.rows)));
    imshow("混合图", srcimage);
    imshow("原图", ROI);

    /***********************此处代码为split函数的测试与验证***********************
    vector<Mat> channels;
    split(ROI, channels);                            //使用函数进行通道分离

    Mat test= channels.at(1);                        //把分离出来的第一通道赋给test,此时test为单通道图像
    cvtColor(logo,logo,CV_RGB2GRAY);                 //RGB灰度转换为灰度图像,使三通道变为一通道,进行下面的融合。融合必须注意两图像的尺寸和深度(通道)

    addWeighted(test, 0.8, logo, 0.4, 0, logo);  
    imshow("混合图1", logo);

    channels.at(0) = 0;
    merge(channels, ROI);   imshow("混合图2", ROI);
    */


    //四种方法的调用函数
    bluechannel(ROI, outputImage);
    greenchannel(ROI, outputImage);
    redchannel(ROI, outputImage);
    channel(ROI, outputImage);

    waitKey();
    return 0;
}


//矩阵元素访问的四种方法:指针、迭代器和动态地址计算法
//1.分离蓝色通道——用指针访问像素
void bluechannel(Mat inputImage, Mat outputImage)
{
    outputImage = inputImage.clone();
    int nrow = outputImage.rows;
    int ncol = outputImage.cols * outputImage.channels();
    for (int i = 0; i<nrow; i++){
        uchar* data = outputImage.ptr<uchar>(i);        //指针指向每一行的开头
        for (int j = 0; j<ncol; j++)
        {
            if (j % 3 != 0)                                 //一二通道像素为0,对第三通道数据不作处理
                data[j] = 0;
        }
    }
    imshow("蓝色通道图", outputImage);

}


//2.分离绿色通道——用迭代器访问像素
void greenchannel(Mat inputImage, Mat outputImage)
{
    outputImage = inputImage.clone();

    Mat_<Vec3b>::iterator itbegin = outputImage.begin<Vec3b>();
    Mat_<Vec3b>::iterator itend = outputImage.end<Vec3b>();

    //三通道处理
    for (; itbegin != itend; itbegin++)
    {
        (*itbegin)[0] = 0;
        (*itbegin)[1] = (*itbegin)[1];
        (*itbegin)[2] = 0;
    }
    imshow("绿色通道图", outputImage);

}


//3.分离红色通道——用动态地址计算访问像素
void redchannel(Mat inputImage, Mat outputImage)
{
    outputImage = inputImage.clone();
    //三通道处理
    for (int i = 0; i<outputImage.rows; i++)
    for (int j = 0; j<outputImage.cols; j++)
    {
        outputImage.at<Vec3b>(i, j)[0] = 0;
        outputImage.at<Vec3b>(i, j)[1] = 0;
        outputImage.at<Vec3b>(i, j)[2] = outputImage.at<Vec3b>(i, j)[2];
    }
    imshow("红色通道图", outputImage);

}

//4.三通道全为零——用下标法访问像素(指针法)
void channel(Mat inputImage, Mat outputImage)
{
    outputImage = inputImage.clone();
    //uchar* data = outputImage.data; 
    uchar* data = outputImage.ptr();    // 这行和上行代码功能相同,使指针指向图像存储区的开头
    int step = outputImage.step;
    for (int i = 0; i<outputImage.rows; i++)
    for (int j = 0; j < outputImage.cols; j++)
    {
        data[i*step + j*outputImage.channels() + 0] = 0;
        data[i*step + j*outputImage.channels() + 1] = 0;
        data[i*step + j*outputImage.channels() + 2] = 0;
    }

    imshow("三通道全为零", outputImage);

}

本文写了四种最简单,直接,容易理解的四种访问图像元素方法,并通过图像的三通道分离进行了举例说明。其中星号注释的部分是对opencv提供的库函数split的使用和验证。
更多访问图像元素的方法请参考博客:http://blog.csdn.net/xiaowei_cqu/article/details/19839019

效果图:这里写图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值