算术操作无非就是像数值之间的加减乘除操作
一、创建图像像素算术操作——头文件
在项目的头文件中,右击添加,新建项
创建用于图像像素算术操作的头文件,我这边是operater.h
该头文件声明了一个Operater类(class Operater
),该类下面声明一个函数(void mat_operater(Mat& image)
)
operater.h
头文件内容如下:
#pragma once
#include <opencv2/opencv.hpp>
using namespace cv;
class Operater {
public:
void mat_operater(Mat& image);
};
二、创建图像像素算术操作——函数实现
创建个文件,用于实现头文件中Operater
类中的mat_operater
函数
我这个文件是:operate.cpp
#include"operater.h"
,导入自定义的头文件
Mat hjj,result;
,定义两个matrix,hjj为需要改变的像数值,result为改变之后的最终结果
Mat::zeros(image.size(), image.type());
,初始化成和原始图像image大小规格一致
hjj = Scalar(50, 50, 50);
,对原始图像三通道都操作50哥像数值
add(image, hjj, result);
,加法操作
参数一:原始图片
参数二:要改变多少像数值
参数三:最终的结果
这里就是:对image图像进行加hjj这么多像数值,最终的输出结果为result
当然加减乘除都类似,add、subtract、multiply、divide
imshow("opreate_show", result);
,展示一下最终的图像
#include"operater.h"
#include <iostream>
#include <opencv2/opencv.hpp>
void Operater::mat_operater(Mat& image) {
Mat hjj,result;
hjj = Mat::zeros(image.size(), image.type());
result = Mat::zeros(image.size(), image.type());
hjj = Scalar(50, 50, 50);
add(image, hjj, result); //加法操作
/*
subtract(image, hjj, result);//减法操作
multiply(image, hjj, result);//乘法操作
divide(image, hjj, result); //除法操作
*/
namedWindow("opreate_show", WINDOW_FREERATIO);
imshow("opreate_show", result);
waitKey(0);
destroyAllWindows();
}
补充:上述都是直接调用OpenCV的函数,下面简述下add函数的大致实现思路,下面的代码与上述直接调用API效果相同,当然肯定没有直接调用API效果好,这里只是演示下实现的思路
详细可参考博文:四、图像像素读写操作
saturate_cast<uchar>(bgr[0] + p[0]);
,因为是像数值相加,可能会越界,故通过函数saturate_cast进行限制,超过255的值一律按255进行处理
#include"operater.h"
#include <iostream>
#include <opencv2/opencv.hpp>
void Operater::mat_operater(Mat& image) {
Mat hjj,result;
hjj = Mat::zeros(image.size(), image.type());
result = Mat::zeros(image.size(), image.type());
hjj = 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 bgr = image.at<Vec3b>(row, col);
Vec3b p = hjj.at<Vec3b>(row, col);
result.at<Vec3b>(row, col)[0] = saturate_cast<uchar>(bgr[0] + p[0]);
result.at<Vec3b>(row, col)[1] = saturate_cast<uchar>(bgr[1] + p[1]);
result.at<Vec3b>(row, col)[2] = saturate_cast<uchar>(bgr[2] + p[2]);
}
}
namedWindow("opreate_show", WINDOW_FREERATIO);
imshow("opreate_show", result);
waitKey(0);
destroyAllWindows();
}
三、创建图像像素算术操作——主函数调用
同理,创建一个cpp文件,我这里以yy_main.cpp
为例,作为程序执行入口,调用所实现的方法。
#include "operater.h""
,导入自定义的头文件
Operater yy;;
,对这个类进行赋予对象
yy.mat_operater(src);
,调用这个类中的mat_operater
函数
#include <opencv2/opencv.hpp>
#include <iostream>
#include "operater.h"
using namespace cv;
using namespace std;
int main(int argc, char** argv) {
Mat src = cv::imread("E:/C++_workspace/beyond.jpg", IMREAD_COLOR);
if (src.empty()) {
printf("load image is false...\n");
return -1;
}
namedWindow("yanyu", WINDOW_FREERATIO);
imshow("yanyu", src);
Operater yy;
yy.mat_operater(src);
waitKey(0);
destroyAllWindows();
return 0;
}
项目结构如下:
运行结果如下:
左边为原图,右边为所有像素点值+50之后的图像