图像对象像素点读写操作-CSDN博客中,我们已经掌握了对图像像素点的遍历以及简单读写,这一节就对图像像素进行常规的算术操作。

常见的加减乘除在图像像素点均可实现;同样,我们重新在Demo类中定义一个新的像素点操作函数,这个类我们可以不断添加新的函数,汇总便于回头总结所学的所有小节。

class Demo{
public:
    void colorspace_Demo(Mat &image);
    void Mat_creat(Mat &image);
    void pixel_RW_Demo(Mat &image);
    void operator_Demo(Mat &image);
};

接下来就对这个函数进行定义:

void Demo::operator_Demo(Mat &image)
{
    Mat dst;
    dst = image - Scalar(50,50,50);
    imshow("减法",dst);
}

这里忘记 Scalar建议去复习,这里我们运行观察变化

同样的我们可以进行其他算术操作。这里不再展示。

到这里就已经学会简单的运算操作了,上述的方法存在的问题是,Scalar这里是像素点值,那如果是图片能不能成功呢?话不多说,动手操作。

好的,这里我为了复习之前学的对象图像的创建,我就直接创建一个图像用Scalar给其像素点赋值。

Mat dst = Mat::zeros(image.size(),image.type());
dst = Scalar(50,50,50);
dst=dst - image;
imshow("减法",dst);

修改函数定义,我们运行结果没有任何问题。

那么好接下来就是一些算术运算注意的地方:

1.所运算的两张图像的大小,type要保持一致。

Mat dst = Mat::zeros(image.size(),image.type());

 2.算术运算的像素点值要在0-255之间,在做乘法和除法运算时最应该注意。 

同时,opencv中有saturate_cast<uchar>()函数去自动给出最大最小限制;

saturate_cast<uchar>()函数介绍:

<>中填的是括号内的类型,因为图像像素点为0-255,那<>中应该是uchar(unisgned char)

下面给出示例:

void Demo::operator_Demo(Mat &image)
{
    // Mat dst;
    // dst = image - Scalar(50,50,50);
    // imshow("减法",dst);

    Mat dst = Mat::zeros(image.size(),image.type());
    dst = Scalar(50,50,50);
    // dst = image - dst;


    int h = image.rows;
    int w = image.cols;
    for (int row = 0;row < h;row++)
         for (int col = 0;col < w;col++)
         {

            Vec3b bgr_image =  image.at<Vec3b>(row,col);
            Vec3b bgr_dst =  dst.at<Vec3b>(row,col);
            dst.at<Vec3b>(row,col)[0]= bgr_image[0] - bgr_dst[0]; 
            dst.at<Vec3b>(row,col)[1]= bgr_image[1] - bgr_dst[1]; 
            dst.at<Vec3b>(row,col)[2]= bgr_image[2] - bgr_dst[2]; 

            // dst.at<Vec3b>(row,col)[0]= saturate_cast<uchar>(bgr_image[0] - bgr_dst[0]); 
            // dst.at<Vec3b>(row,col)[1]= saturate_cast<uchar>(bgr_image[1] - bgr_dst[1]);  
            // dst.at<Vec3b>(row,col)[2]= saturate_cast<uchar>(bgr_image[2] - bgr_dst[2]);  
            
         }

     imshow("减法",dst);
}

这段代码是对每一个像素点进行减法运算,我们分别注释运行,用结果说话:

很显然,如果我们没有考虑像素点值大小的话,结果是不正确的;

最后,opencv中是有提供便捷的算术运算函数使用:

1.加法:add(image1,image2,dst);

2.减法:subtract(image1,image2,dst);

3.乘法:multiply(image1,image2,dst);

4.除法:divide(image1,image2,dst);

这里的参数都是前两个是输入运算的图像,最后是输出的图像;同样注意的是:两图尺寸、通道数必须一致;

Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐