ITKeyword,专注技术干货聚合推荐

注册 | 登录

OpenCV2 访问各个像素点的方法(图像遍历)

jenny_84 分享于

2020腾讯云限时秒杀,爆款1核2G云服务器99元/年!(领取2860元代金券),
地址https://cloud.tencent.com/act/cps/redirect?redirect=1062

2020阿里云最低价产品入口+领取代金券(老用户3折起),
入口地址https://www.aliyun.com/minisite/goods

推荐:[OpenCV2]遍历图像的临近像素 - 博客频道 - CSDN.NET

在图像处理中,经常需要处理一个当前点这个点的值可能是基于附近几个临近像素点而得出的.当临近像素点包含上一行或者下一行数据的时候,你需要同时扫描图像的多行.

转载于此文

内容来自《OpenCV 2 Computer Vision Application Programming Cookbook》

OpenCV2 访问图像的各个像素有各种方法

我们来用各种方法来实现减少图像的颜色数量

color = color/div*div +div/2;

若div为8,则原来RGB每个通道的256种颜色减少为32种。

若div为64,则原来RGB每个通道的256种颜色减少为4种,此时三通道所有能表示的颜色有4×4×4 = 64 种

以上运算请参考我的博客减少图像颜色数量的运算
首先,我们来看一个函数

C++: uchar* Mat::ptr(int i=0)
i 是行号,返回的是该行数据的指针。
在OpenCV中,一张3通道图像的一个像素点是按BGR的顺序存储的。
先来看看第一种访问方案

void colorReduce1(cv::Mat& image, cv::Mat& result, int div=64){
    int nrow = image.rows;
    int ncol = image.cols * image.channels();
    for(int i=0; i<nrow; i++){
        uchar* data = image.ptr<uchar>(i);
        uchar* data_out = result.ptr<uchar>(i);
        for(int j=0; j<ncol; j++){
            data_out[j] = data[j]/div*div +div/2;
        }
    }
}

复制代码
第二种方案:

推荐:图像的像素点操作【OpenCV学习笔记3】

/* 功能:读入图像文件,做图像反转,然后显示图像在屏幕上 */ #include "stdafx.h" #include <stdlib.h> #include <stdio.h> #include <math.h> #include <cv.h

先来看如下函数:

C++: bool Mat::isContinuous() const

C++: Mat Mat::reshape(int cn, int rows=0) const

出于性能方面的考虑,在图像每一行的最后可能会填充一些像素,这样图像的数据就不是连续的了

我们可以用函数isContinuous()来判断图像的数据是否连续

reshape函数的作用如下:

Changes the shape and/or the number of channels of a 2D matrix without copying the data.

这样,我们就提出了对第一种方法的改进

void colorReduce2(cv::Mat& image, cv::Mat& result, int div){
    if(image.isContinuous()){
        image.reshape(1,image.cols*image.rows);
    }
    int nrow = image.rows;
    int ncol = image.cols * image.channels();
    for(int i=0; i<nrow; i++){
        uchar* data = image.ptr<uchar>(i);
        uchar* data_out = result.ptr<uchar>(i);
        for(int j=0; j<ncol; j++){
            data_out[j] = data[j]/div*div +div/2;
        }
    }
}

第三种方案:
先来看看下面的函数
C++: template T& Mat::at(int i, int j)
其作用是Returns a reference to the specified array element.

void colorReduce3(cv::Mat& image, cv::Mat& result, int div){
    int nrow = image.rows;
    int ncol = image.cols * image.channels();
    for(int i=0; i<nrow; i++){
        for(int j=0; j<ncol; j++){
            image.at<cv::Vec3b>(j,i)[0]= image.at<cv::Vec3b>(j,i)[0]/div*div + div/2;
            image.at<cv::Vec3b>(j,i)[1]= image.at<cv::Vec3b>(j,i)[1]/div*div + div/2;
            image.at<cv::Vec3b>(j,i)[2]= image.at<cv::Vec3b>(j,i)[2]/div*div + div/2;
        }
    }
}

第四种方案是使用迭代器
会使用到如下函数:
C++: template MatIterator_<_Tp> Mat::begin()
C++: MatIterator_<_Tp> Mat::end()

关于迭代器的使用,可参考我的博客:迭代器:访问string对象和vector对象

void colorReduce4(cv::Mat& image, cv::Mat& result, int div){
    cv::Mat_<cv::Vec3b>::iterator it = image.begin<cv::Vec3b>();
    cv::Mat_<cv::Vec3b>::iterator itend = image.end<cv::Vec3b>();
    cv::Mat_<cv::Vec3b>::iterator itout = result.begin<cv::Vec3b>();
    for(; it!=itend; ++it,++itout){
        (*itout)[0] = (*it)[0]/div*div + div/2;
        (*itout)[1] = (*it)[1]/div*div + div/2;
        (*itout)[2] = (*it)[2]/div*div + div/2;
    }
}

推荐:【OpenCV】OpenCV中获取图像的像素点并处理

#include <iostream> using namespace std; #include "cv.h" #include "highgui.h" #pragma  comment(lib,"cxcore.lib") #pragma  comment(lib,"cv.lib") #pragm

转载于此文 内容来自《OpenCV 2 Computer Vision Application Programming Cookbook》 OpenCV2 访问图像的各个像素有各种方法 我们来用各种方法来实现减少图像的颜色数量 color = color/div*div

相关阅读排行


相关内容推荐

最新文章

×

×

请激活账号

为了能正常使用评论、编辑功能及以后陆续为用户提供的其他产品,请激活账号。

您的注册邮箱: 修改

重新发送激活邮件 进入我的邮箱

如果您没有收到激活邮件,请注意检查垃圾箱。