opencv3_note2:使用三种方式遍历像素

1.什么是一幅图像———(摘自《数字图像处理疑难解析》)

1.就单色图像而言,是一个二维的光强函数f(x,y),其中的x和y是空间坐标,f(x,y)正比于图像在该点的亮度值;若是一幅彩色图,则f

是一个向量,每一个分量代表着一个颜色分量

2.数字图像在空间坐标和亮度值都离散化的图像f(x,y)中,它可以用一个或者若干个数组来表示数组的每一个元素称为像素(pixel)

2.颜色空间缩减算法

2-1:有的时候 单通道图的像素值可以有0-255种,但是,如果三通道的图可以有255^3种类别,在适当的时候,对像素值进行省略可以简化计算量

2-2:算法公式

a=(a/div+div)+div/2; 定义合适的div

2-3:算法逻辑实现:

遍历图像矩阵的每一个像素,然后对像素应用上述公式

2-4:

其实算法的实现并不难,但是,实现像素的遍历值得一提,下面采用三种方式实现遍历像素的效果

#include<opencv2/opencv.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<iostream>
#define PICTURE_ADRESS "C:\\Users\\ASUS\\Pictures\\opencv_Pirture\\2.jpg"

    void colorReduce(cv::Mat &input_picture, cv::Mat &output_picture, int div);
    int main()
    {
        cv::Mat dstImage;
        cv::Mat srcImage = cv::imread(PICTURE_ADRESS);
        if (!srcImage.data)
        {
            std::cout << "read it error" << std::endl;
            return false;
        }
        dstImage.create(srcImage.rows, srcImage.cols, srcImage.type());//初始化dstImage
        colorReduce(srcImage, dstImage, 32);
        cv::imshow("origin_picture", srcImage);
        cv::imshow("result_picture", dstImage);
        
        while (!(char(cv::waitKey(10)) == 's'));//按键退出
        return 0;
        system("pause");
    }


//solution 1:使用指针 方法运行效率高,但是比较难以理解
    /*void colorReduce(cv::Mat& input_picture, cv::Mat& output_picture, int div)
    {
        output_picture = input_picture.clone();//创建副本
        int row_num = output_picture.rows;
        int col_num = output_picture.cols*output_picture.channels();//将类和通道数归一处理
        for (int i = 0; i < row_num; i++)
        {
            uchar *data = output_picture.ptr<uchar>(i);//获取第i行的首地址
            for (int j = 0; j < col_num; j++)
            {
                data[j] = data[j] / div*div + div / 2;//核心算法
            }
        }
    }*/
//solution2 :使用迭代器进行像素的访问 需要会使用一些向量
    /*void colorReduce(cv::Mat& input_picture, cv::Mat& output_picture, int div)
    {
        output_picture = input_picture.clone();
        //定义迭代器
        cv::Mat_<cv::Vec3b>::iterator it = output_picture.begin<cv::Vec3b>();
        cv::Mat_<cv::Vec3b>::iterator itend = output_picture.end<cv::Vec3b>();
        //一般的三通道图像处理方法
        for (; it != itend; it++)
        {
            (*it)[0] = (*it)[0] / div*div + div / 2;
            (*it)[1] = (*it)[1] / div*div + div / 2;
            (*it)[2] = (*it)[2] / div*div + div / 2;
        }
    }*/
//solution3 :使用动态地址计算 .at方法 简单易懂 但是运行效率没有前两种高(个人推荐)
    void colorReduce(cv::Mat& input_picture, cv::Mat& output_picture, int div)
    {
        output_picture = input_picture.clone();    
        int col_num = output_picture.cols;
        int row_num = output_picture.rows;
        for (int i = 0; i < row_num; i++)
        {
            for (int j = 0; j < col_num; j++)
            {
                output_picture.at<cv::Vec3b>(i, j)[0] = output_picture.at<cv::Vec3b>(i, j)[0] / div*div + div / 2;
                output_picture.at<cv::Vec3b>(i, j)[1] = output_picture.at<cv::Vec3b>(i, j)[1] / div*div + div / 2;
                output_picture.at<cv::Vec3b>(i, j)[2] = output_picture.at<cv::Vec3b>(i, j)[2 ] / div*div + div / 2;

            }
        }

        //其实三种方法都是用不同的方式提取出了图像中的像素点 然后加以处理
        //pixel=pxel/div*div+div/2;
    }

2-5:效果图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值