需求:因为需要用手机拍照后进行全景图拼接,但是因为不同角度去拍摄经常会因为灯光的亮度问题导致无法识别匹配点,所以考虑在拼接前调整图片的亮度和对比度
方案1:调整手机的曝光补偿
这种方法理论上可行,不过由于我做的是浏览器的,原生安卓和ios可以调用api去调整手机的曝光补偿,浏览器端navigator.mediaDevices.getUserMedia并没有提供控制曝光补偿的api,所以不可行。
方案2:通过opencv去调整
opencv有成熟的方案去调整图片和对比度,但是前端项目运行opencv实在是太卡了,得给nodejs分配10g左右的内存才能运行起来,运行期间卡的飞起来。 不过opencv的处理方式可以提供一些灵感 可以跳过这一段 后面我会讲vue版本的
int main()
{
s_param sp;
//输入图像
sp.img = imread("aa.png", 1);
if (!sp.img.data || sp.img.channels() != 3)
return 0;
imshow("from", sp.img);
//彩色图像的灰度值归一化
sp.img.convertTo(sp.bgr, CV_32FC3, 1.0 / 255, 0);
//颜色空间转换
cvtColor(sp.bgr, sp.hsv, cv::COLOR_BGR2HSV);
//Mat img(200, 300, CV_8UC1);
std::vector<cv::Mat> channels;
split(sp.hsv, channels);
int nWidth = sp.img.cols;
int nHeight = sp.img.rows;
Mat src = sp.img;
Mat dst = src.clone();
float alpha = 0.8;
float beta = 30;
for (int row = 0; row < nHeight; row++)
{
for (int col = 0; col < nWidth; col++)
{
float b = src.at<Vec3b>(row, col)[0];
float g = src.at<Vec3b>(row, col)[1];
float r = src.at<Vec3b>(row, col)[2];
dst.at<Vec3b>(row, col)[0] = saturate_cast<uchar>(b *alpha +beta);
dst.at<Vec3b>(row, col)[1] = saturate_cast<uchar>(g *alpha + beta);
dst.at<Vec3b>(row, col)[2] = saturate_cast<uchar>(r *alpha +beta);
}
}
imshow("dst", dst);
waitKey(0);
}
原文链接:blog.csdn.net/qianbo04231…
方案3:通过canvas调整
processImage() {
//创建一个Image对象
const img = new Image();
//设置图片
img.src = this.imageUrl;
img.onload = () => {
//创建canvas
const canvas = document.createElement('canvas');
//获得canvas的2d对象
const ctx = canvas.getContext('2d');
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage(img, 0, 0);
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
//通过访问`ImageData`对象的`data`属性,获取一个`Uint8ClampedArray`类型的数组,该数组直接引用了图像数据
const data = imageData.data;
//使用一个循环遍历每个像素的数据。每个像素由四个连续的数组元素表示,分别是红色通道、绿色通道、蓝色通道和透明度通道
for (let i = 0; i < data.length; i += 4) {
const r = data[i];
const g = data[i + 1];
const b = data[i + 2];
//对每个通道的像素值进行调整,使用`Math.min`函数确保像素值不超过255
// alpha和beta是用于调整图像亮度和对比度的参数。
//通过调整alpha和beta的值,可以改变图像的亮度和对比度,从而达到不同的视觉效果。
data[i] = Math.min(255, r * this.alpha + this.beta);
data[i + 1] = Math.min(255, g * this.alpha + this.beta);
data[i + 2] = Math.min(255, b * this.alpha + this.beta);
}
//将处理后的图像数据放回画布
ctx.putImageData(imageData, 0, 0);
//将处理后的图像显示在画布上
this.processedImageUrl = canvas.toDataURL();
this.processedImage = true;
};
}