计算机系统应用教程网站

网站首页 > 技术文章 正文

计算机视觉学习笔记3 图像的像素运算

btikc 2024-09-08 12:09:49 技术文章 22 ℃ 0 评论

图像本质上来讲就是一个矩阵,矩阵中每一个元素都对应着像素点的像素值,所以矩阵中的每个元素都是能进行代数运算,点运算和逻辑运算的。

做神经网络和三维点云去了,这些基础知识一段时间了不用就忘完了,再复习一下。

图像点运算

点运算又称为对比度增强,对比度拉伸或灰度拉伸,是通过图像中的每一个像素值进行运算的图像处理方式,运算不会改变图像像素点之间的空间关系。

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都只做了加减乘除运算。还有很坑的一点是,有些时候会出现图像一片黑或者一片白的情况,主要原因是因为数值超出图像像素范围了,需要另外进行调整。

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表