图像本质上来讲就是一个矩阵,矩阵中每一个元素都对应着像素点的像素值,所以矩阵中的每个元素都是能进行代数运算,点运算和逻辑运算的。
做神经网络和三维点云去了,这些基础知识一段时间了不用就忘完了,再复习一下。
图像点运算
点运算又称为对比度增强,对比度拉伸或灰度拉伸,是通过图像中的每一个像素值进行运算的图像处理方式,运算不会改变图像像素点之间的空间关系。
MATLAB中通过 imadjust()进行线性灰度变换 还可以把图像当做一个函数来进行非线性灰度变换
图像的代数运算
- 图像的加法运算
加法运算主要是将一幅图像内容叠加到另一幅图像上,或者对每个像素叠加常数改变其亮度。
调用方法:
result 为输出结果,img1和img2为要叠加的图像
MATLAB: result = imadd(img1, img2); c++ : add(img1, img2, result); python: cv.add(img1, img2, result)
- 图像的减法运算
图像减法运算也叫差分方法,是一种常用于检测图像变换及运动物体的图像处理方法。比如可以用来检测一系列相同场景之间的差异
值得注意的是,图像相减次序不同结果也不一样的。
调用方法:
MATLAB: result = imsubtract(img1, img2); c++ : subtract(img1, img2, result); python: cv.subtract(img1, img2, result);
- 图像的乘法运算
图像的乘法运算一般来讲没啥用,可以用来屏蔽图像的某些部分,或者是乘某个常数因子,比如1.5或者0.5,用来增强图像亮度或则变暗。
调用方法:
MATLAB: result = immultiply(img1, img2); c++ : multiply(img1, img2, result); python: cv.multiply(img1, img2, result);
- 图像的除法运算
图像的除法运算好像也没啥用,能得到两幅图像之间的变化率,因此图像除法也称为比率变换,用来校正成像设备的非线性影响。
调用方法:
MATLAB: result = imdivide(img1, img2); c++ : divide(img1, img2, result); python: cv.divide(img1, img2, result);
相信大家也看出来了,调用方法就是四则运算的名称,并且MATLAB干啥都喜欢加上im,如imadd,c++比较直接,python需要加上前缀cv.。
MATLAB实现图像代数运算
代码后面有注释,就不在正文中讲解了。用到了四个图像,示例图像OpenCV或者MATLAB自带的库里面都能找到。
img1 = imread('data/rice.bmp'); img2 = imread('data/cameraman.tif'); img3 = imread('data/ipexroundness_02.png'); img4 = imread('data/ipexroundness_01.png'); add1 = imadd(img1,img2); %进行两幅图像的加法运算 add2 = imadd(img2, 50); %每个像素值增加30 gs = imnoise(img3,'gaussian',0,0.5); %加入高斯白噪声 for i=1:3 % 叠加三次高斯噪声 gs=imadd(gs, img3); %对用原图像与带噪声图像进行多次叠加,结果返回给 end sub1 = imsubtract(img3, img4); % 图像减法 sub2 = imsubtract(img4, img3); mul = immultiply(img3, img4); % 图像乘法 div = imdivide(img3, img4); % 图像除法 imshow(gs); title('添加高斯噪声'); figure; imshow(mul); title('图3乘图4'); 略。。。
c++实现图像的代数运算
直接上代码,c++没有集成一个图像框显示多个图像的功能,因此添加了mergeImg模块,把四个图像放进去。
#include <opencv2/opencv.hpp> #include <iostream> #include <opencv2/highgui/highgui_c.h> using namespace cv; using namespace std; // 声明一个大的Mat窗口,把四个图像放进去 // Rect提取ROI区域,然后copyto到ROI区域 void mergeImg(Mat & dst, Mat & img1, Mat &img2, Mat &img3, Mat &img4){ int row = img1.rows + 10 + img2.rows; int col = img1.cols + 10 + img2.cols; CV_Assert(img1.type() == img2.type()); dst.create(row, col, img1.type()); img1.copyTo(dst(Rect(0,0,img1.cols, img1.rows))); img2.copyTo(dst(Rect(img1.cols + 10, 0,img2.cols, img2.rows))); img3.copyTo(dst(Rect(0, img1.rows + 10, img3.cols, img3.rows))); img3.copyTo(dst(Rect(img1.cols +10, img1.rows + 10, img4.cols, img4.rows))); } int main(int argc, char **argv){ Mat img1 = imread("data/images/cameraman.tif"); Mat img2 = imread("data/images/rice.bmp"); if (img1.empty() || img2.empty()){ cerr << "Could't load image \n"; return -1; } Mat add_result = Mat::zeros(img1.size(), img1.type()); add(img1, img2, add_result); // 加法 Mat sub_result = Mat::zeros(img1.size(), img1.type()); subtract(img1, img2, sub_result); // 减法 Mat mul_result = Mat::zeros(img1.size(), img1.type()); multiply(img1, img2, mul_result); // 乘法 Mat div_result = Mat::zeros(img1.size(), img1.type()); divide(img1, img2, div_result); // 除法 Mat Image; 调用mergeImg,实现四个图像一起显示 mergeImg(Image, add_result, sub_result, mul_result, div_result); namedWindow("Image", CV_WINDOW_AUTOSIZE); imshow("Image", Image); waitKey(0); return 0; }
只进行的简单的四则运算,效果和MATLAB差不多。
python实现图像代数运算
具体实现过程如下,python运行速度比MATLAB和c++都要慢很多
import cv2 as cv import numpy as np img1 = cv.imread("data/images/cameraman.tif") img2 = cv.imread("data/images/rice.bmp") add_result = np.zeros(img1.shape, img1.dtype) cv.add(img1, img2, add_result) # 加法运算 cv.imshow("add", add_result) sub_result = np.zeros(img1.shape, img1.dtype) cv.subtract(img1, img2, sub_result) # 减法运算 cv.imshow("sub", sub_result) mul_result = np.zeros(img1.shape, img1.dtype) cv.multiply(img1, img2, mul_result) # 乘法运算 cv.imshow("mul", mul_result) div_result = np.zeros(img1.shape, img1.dtype) cv.divide(img1, img2, div_result) # 除法运算 cv.imshow("div", div_result) cv.waitKey(0) cv.destroyAllWindows()
总结:因为MATLAB更简洁,所以就用MATLAB来演示,c++和python都只做了加减乘除运算。还有很坑的一点是,有些时候会出现图像一片黑或者一片白的情况,主要原因是因为数值超出图像像素范围了,需要另外进行调整。
本文暂时没有评论,来添加一个吧(●'◡'●)