牛骨文教育服务平台(让学习变的简单)
博文笔记

OPENCV2 访问图像像素值的三种方法

创建时间:2015-08-19 投稿人: 浏览次数:4958

访问图像像素值是图像处理的基本操作。OPENCV2提供了很多中访问方式,本文实现了其中比较常用的三种方式:
(1) 通过指针访问
(2) 通过迭代器访问
(3) 动态地址计算,通过at()函数实现

方法比较:
(1)用指针访问像素,速度最快;但在彩色图像处理中,如果要单独对某一个颜色分量处理,则需要通过数学公式计算,不是很直观;
(2)推荐用通过迭代器访问像素,速度快,而且提取BGR某一颜色分量很方便。
(3)at()函数适用于随机访问某个具体的像素点(已知该像素点行、列坐标),不建议用at()函数遍历整个图。

本文基于以上方法,分别对灰度图和彩色图进行全图遍历,实现图像阈值处理。具体实现代码如下,且在vs2010测试通过。

#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/photo/photo.hpp"

#include <iostream>
using namespace std;
using namespace cv;

//访问图像像素点,实现阈值处理
void GetGrayImgIntensityByPointer()
{
    Mat srcImg, dstImg;
    srcImg = imread("D:/openCV/data/naturalImage/data/redComponetImg.jpg", 0);
    dstImg = srcImg.clone();//复制,不建议直接对原图处理
    int rows = dstImg.rows;
    int cols = dstImg.cols * dstImg.channels();
    for(int j = 0; j < rows; j++)
    {
        unsigned char* data = dstImg.ptr(j);//获取每行首地址
        for(int i = 0; i < cols; i++)
        {
            if(data[i] > 190)
                data[i] = 255;
            else
                data[i] = 0;
        }
    }
    imshow("原图像", srcImg);
    imshow("阈值处理后图像", dstImg);
    waitKey(0);
}

void GetGrayImgIntensityByInterator()
{
    Mat srcImg, dstImg;
    srcImg = imread("D:/openCV/data/naturalImage/data/redComponetImg.jpg", 0);
    dstImg = srcImg.clone();//复制,不建议直接对原图处理
    Mat_<uchar>::iterator it = dstImg.begin<uchar>();
    Mat_<uchar>::iterator itend = dstImg.end<uchar>();
    for(; it != itend; it++)
    {
        if(*it > 190)
            *it = 255;
        else
            *it = 0;
    }
    imshow("原图像", srcImg);
    imshow("阈值处理后图像", dstImg);
    waitKey(0);
}

void GetColorImgIntensityByPointer()
{
    Mat srcImg, dstImg;
    srcImg = imread("D:/openCV/data/naturalImage/data/opencv.jpg", 1);
    dstImg = srcImg.clone();//复制,不建议直接对原图处理
    int rows = dstImg.rows;
    int cols = dstImg.cols * dstImg.channels();
    for(int j = 0; j < rows; j++)
    {
        unsigned char* data = dstImg.ptr(j);//获取每行首地址
        for(int i = 0; i < cols; i++)
        {
            int ii = i % 2;
            if(ii != 0)
                data[i] = 0;
            else
            {
                if(data[i] > 190)//对红色分量设置阈值,速度和效果都比不上迭代器
                    data[i] = 255;
                else
                    data[i] = 0;
            }
        }
    }
    imshow("原图像", srcImg);
    imshow("阈值处理后图像", dstImg);
    waitKey(0);
}

void GetColorImgIntensityByInterator()
{
    Mat srcImg, dstImg;
    srcImg = imread("D:/openCV/data/naturalImage/data/opencv.jpg", 1);
    dstImg = srcImg.clone();//复制,不建议直接对原图处理
    Mat_<Vec3b>::iterator it = dstImg.begin<Vec3b>();
    Mat_<Vec3b>::iterator itend = dstImg.end<Vec3b>();
    for(; it != itend; it++)
    {
        if((*it)[2] > 190)
        {
            (*it)[0] = 0;
            (*it)[1] = 0;
            (*it)[2] = 255;
        }

        else
        {
            (*it)[0] = 0;
            (*it)[1] = 0;
            (*it)[2] = 0;
        }
    }
    imshow("原图像", srcImg);
    imshow("阈值处理后图像", dstImg);
    waitKey(0);
}

void RandomGetIntensity()//没用到颜色缩减
{
    Mat srcImg, dstImg;
    srcImg = imread("D:/openCV/data/naturalImage/data/opencv.jpg", 1);
    dstImg = srcImg.clone();//复制,不建议直接对原图处理
    for(int j = 0; j < dstImg.rows; j++)
        for(int i = 0; i < dstImg.cols; i++)
        {
            if(dstImg.at<Vec3b>(j, i)[2] > 190)
            {
                dstImg.at<Vec3b>(j, i)[0] = 0;
                dstImg.at<Vec3b>(j, i)[1] = 0;
                dstImg.at<Vec3b>(j, i)[2] = 255;
            }
            else
            {
                dstImg.at<Vec3b>(j, i)[0] = 0;
                dstImg.at<Vec3b>(j, i)[1] = 0;
                dstImg.at<Vec3b>(j, i)[2] = 0;
            }
        }
        imshow("原图像", srcImg);
        imshow("阈值处理后图像", dstImg);
        waitKey(0);
}

int main(int argc, char* argv[])
{
    //GetGrayImgIntensityByPointer();
    GetGrayImgIntensityByInterator();//效果好,速度快
    //GetColorImgIntensityByInterator();
    //GetColorImgIntensityByPointer();
    //RandomGetIntensity();
    return 0;
}

对灰度图阈值处理,效果图如下:

这里写图片描述

声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。