05 图像像素的算术操作

05 图像像素的算术操作

opencv知识点:

  • 图像像素算术操作 - 运算符

  • 值的截断 - saturate_cast<>()

  • 图像像素算术操作 - 专用函数

本课所解决的问题:

  • 如何改变图像的亮度?
  • 如何进行图像像素的算术操作?
  • 如何对可能溢出的值进行截断?

1.改变图像亮度

对于改变图像的亮度,我们可以采用图像像素的算术操作实现

本文采用如下两种方法演示

  • 四种运算运算符
  • 四种专用函数

2.四种运算符和截断

运算符(调节图像的亮度的几种方法)#

首先,我们采用运算符的方式 (调节亮度)

程序#

main.cpp#

#include "opencv2/opencv.hpp"
#include "quickopencv.h"
#include <iostream>

using namespace cv;
using namespace std;

int main(int argc, char** argv) {
	Mat src = imread("C:/Users/LZQ/Desktop/lena.png"); //  B, G, R
	if (src.empty()) {
		printf("could not load image....\n");
		return -1;
	}
	//namedWindow("输入窗口", WINDOW_FREERATIO);
	imshow("输入窗口", src);

	QuickDemo qd;

	qd.operators_demo(src);    //05   <---------------------------修改的程序(唯一的修改部分)
	waitKey(0);
	destroyAllWindows();
	return 0;
}

quickdemo.cpp#

#include "quickopencv.h"
#include <opencv2/dnn.hpp>

using namespace cv;
using namespace std;
void QuickDemo::operators_demo(Mat& image) {

	Mat dst;

	dst = image + Scalar(50, 50, 50);  //加法操作
	//dst = image - Scalar(50, 50, 50);  //减法操作
	//dst = image * Scalar(5, 5, 5);//会溢出      //乘法操作
	//dst = image / Scalar(5, 5, 5);//会截断为0   //除法操作
	imshow("加法操作", dst);

quickopencv.h#

pragma once

#include <opencv2/opencv.hpp>

using namespace cv;

class QuickDemo {            //快速的演示文件 class类
public:

	void operators_demo(Mat& image);                //  <-----------------修改的程序(唯一的修改部分)

};

结果#

加法:#

图像变亮,可能会溢出

70784c9797816ab616dfff0c0f278fa

减法:#

图像变暗,会自动截断为0

18cae9d943d5097dd59565b382e5c3b

乘法:#

可能会溢出,提示溢出的错误。
本案例就溢出了,所以没有结果展示

c8020e834999a1cb767409b6648ddd1

除法:#

除法:如果除数较大,结果最终会被自动截断为0

0224a25da111360f7a4ca79adfa8a3d

截断函数#

采用运算符时加法,乘法有溢出隐患,有什么办法解决吗?
这就用到了saturate_cast<uchar>,当使用它时会保证BGR图像的像素值在[0,255]

对于截断的演示,我们用运算符加法演示

quickdemo.cpp#

其余的程序和上面一样

#include "quickopencv.h"
#include <opencv2/dnn.hpp>

using namespace cv;
using namespace std;
void QuickDemo::operators_demo(Mat& image) {

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

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

	for (int row = 0; row < h; row++) {
		for (int col = 0; col < w; col++) {
			Vec3b p1 = image.at<Vec3b>(row, col);
			Vec3b p2 = m.at<Vec3b>(row, col);
			dst.at<Vec3b>(row,col)[0] = saturate_cast<uchar>(p1[0] + p2[0]);
			dst.at<Vec3b>(row,col)[1] = saturate_cast<uchar>(p1[1] + p2[1]);
			dst.at<Vec3b>(row,col)[2] = saturate_cast<uchar>(p1[2] + p2[2]);
		}
	}
	imshow("加法操作", dst);

}

3.专用函数

有没有更简单的方式呢?

OpenCV有自带的专用函数,专用函数都有截断处理,以乘法为例。

quickdemo.cpp#

其余部分的程序不变。

#include "quickopencv.h"
#include <opencv2/dnn.hpp>

using namespace cv;
using namespace std;
void QuickDemo::operators_demo(Mat& image) {

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

	//add(image, m, dst);
	//subtract(image, m, dst);
	multiply(image, m,dst);
	//divide(image, m, dst);
	
	imshow("加法操作", dst);
}

296cbf5216f1f2c18c127727de25386

本课所用API查阅

Scalar()#

add()#

subtract()#

multiply()#

divide()#

saturate_cast<>()#

uchar a = saturate_cast<uchar>(-100); // a = 0 (UCHAR_MIN)
short b = saturate_cast<short>(33333.33333); // b = 32767 (SHRT_MAX)
posted @   L707  阅读(61)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
主题色彩