Opencv -- 005图像像素的算数操作

加减乘除操作

05_opencv_mat.h

#pragma once

#ifndef _05_OPENCV_MAT_H
#define _05_OPENCV_MAT_H

#include <opencv2/opencv.hpp>

using namespace cv;

class QuickDemo {
public:
	void operators_demo(Mat& image);
};

#endif

05_opencv_mat.cpp

#include <iostream>
#include "05_opencv_mat.h"

using namespace std;

void QuickDemo::operators_demo(Mat &image)
{
	Mat dst_add, dst_sub;
	
	dst_add = image + Scalar(50, 50, 50);
	dst_sub = image - Scalar(50, 50, 50);
	imshow("像素加法操作演示", dst_add);
	imshow("像素减法操作演示", dst_sub);
}

main.cpp

#include <iostream>
#include "05_opencv_mat.h"

using namespace std;

int main(int argc,char** argv)
{
    //使用Mat(matrix -- 矩阵)这种类型来读取通过指定路径的图像信息并存放到变量picture中。
    //图像从本质上来说都是二维的数组(矩阵)
    Mat picture = imread("雪地.jpeg", IMREAD_COLOR);

    if (picture.empty())
    {
        cout << "could not Load image." << endl;
        system("pause");
        return -1;
    }
    
    // namedWindow("输入窗口",WINDOW_FREERATIO);
   
    imshow("输入窗口", picture);

    QuickDemo qd;
    qd.operators_demo(picture);

    waitKey(0);
    destroyAllWindows();

    system("pause");
    return 0;
}

在这里插入图片描述
结论:从上图中,我们发现,经过加法操作后,图片颜色变白了(变亮了),经过减法操作后,图片的颜色变深了。(变暗了)

仿照前面的操作,我们能否使用 " * " 和 " / " 来完成运算呢?
答:我们可以使用 " / "来完成运算,结果是图像的颜色变深了。但我们不可以直接使用 " * " 来完成运算。(程序会报错)

报错的原因是因为运算的类型不一致。

这时候,我们应该怎么办呢?

Opencv给我们提供了一个专门的函数 multiply

以下是" * " 和" / "的实现过程和代码。

05_opencv_mat.cpp

#include <iostream>
#include "05_opencv_mat.h"

using namespace std;

void QuickDemo::operators_demo(Mat &image)
{
	Mat dst_mul, dst_div;
	Mat temp = Mat::zeros(image.size(),image.type());
	temp = Scalar(2,2,2);

	/*
	@param src1 first input array.--源图像
	@param src2 second input array of the same size and the same type as src1.与源图像相同种类和大小的图像
	@param dst output array of the same size and type as src1.--输出图像
	这个函数还有其他参数,暂不说明。
	*/
	multiply(image, temp, dst_mul);//
	dst_div = image / Scalar(2, 2, 2);
	imshow("像素乘法操作演示", dst_mul);
	imshow("像素除法操作演示", dst_div);
}

在这里插入图片描述
如果乘的结果大于了255,会被自动截断为255。

除此之外,对于上面所介绍的 加、 减、除 也均有相应的 API 函数可以使用。

以加法为例,提供有 add函数。

void QuickDemo::operators_demo(Mat &image)
{
	Mat dst_add;
	Mat temp = Mat::zeros(image.size(),image.type());
	temp = Scalar(50,50,50);

	/*
	@param src1 first input array.--源图像
	@param src2 second input array of the same size and the same type as src1.与源图像相同种类和大小的图像
	@param dst output array of the same size and type as src1.--输出图像
	这个函数还有其他参数,暂不说明。
	*/
	add(image, temp, dst_add);
	imshow("像素加法操作演示", dst_add);
}

实际上,我们还应该能够想到,add这个函数的具体实现过程,可以利用上节课所学的 " 图像像素的读写操作 " 来实现。
这里还需要了解一个函数就是 saturate_cast ,这个函数的作用是类型转换,用作限定数据范围。

saturate_cast<uchar>(p1[0]+p2[0])

比如上面这句代码,它的含义是将 p1[0]+p2[0] 的运算结果限定在uchar数据类型的范围,即 0-255 。

#include <iostream>
#include "05_opencv_mat.h"

using namespace std;

void QuickDemo::operators_demo(Mat &image)
{
	Mat dst_add = Mat::zeros(image.size(), image.type());
	Mat temp = Mat::zeros(image.size(),image.type());

	temp = Scalar(50,50,50);

	int w = image.cols; // 列
	int h = image.rows; // 行
	int dims = image.channels();

	for (int row = 0; row < h; row++)
	{
		for (int col = 0; col < w; col++)
		{
			if(dims == 3)
			{ 
				Vec3b p1 = image.at<Vec3b>(row,col);
				Vec3b p2 = temp.at<Vec3b>(row, col);
				dst_add.at<Vec3b>(row, col)[0] = saturate_cast<uchar>(p1[0]+p2[0]);
				dst_add.at<Vec3b>(row, col)[1] = saturate_cast<uchar>(p1[1] + p2[1]);
				dst_add.at<Vec3b>(row, col)[2] = saturate_cast<uchar>(p1[2] + p2[2]);
			}
		}
	}
	imshow("像素加法操作演示", dst_add);
}

以减法为例,提供有 subtract函数。

subtract(image, temp, dst_add);

以除法为例,提供有 divide函数。

temp = Scalar(50,50,50);
divide(image, temp, dst_add);

运行结果如下:
在这里插入图片描述
为什么会变黑了,是因为我们设置的除数太大了。最终得到的结果太小了,所以变黑了。

将除数从50改为5,运行下:
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xuechanba

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值