灰度图象,像素反转,对比度及亮度调值, 以及两张相同大小图片的混合
一、图像的像素变换:
1.灰度图像生成:
前面用python实现过灰度转换:https://www.cnblogs.com/Jack-Elvis/p/10971603.html
灰度图像的生成办法是由彩色图像的三个通道的像素值取均值后赋给单通道的灰度图像值:
C++代码实现
(1)opencv的API代码如下:
1.输入图像(彩色) 2.自定义的输出图像 3.方法,BGR —GRAY
(2)不用opencvAPI代码实现:
生成一个灰度大小的矩阵:
核心步骤:
RGB到灰度图转换公式:Y' = 0.299 R + 0.587 G + 0.114 B 也可以用 Y=(R+G+B)/3
代码如下:
#include <opencv2/core/core.hpp> #include <opencv2/imgcodecs.hpp> #include <opencv2/opencv.hpp> #include <opencv2/highgui/highgui.hpp> #include <iostream> using namespace cv; using namespace std; int main(int argc, char** args) { Mat image = imread("L:/4.jpg", IMREAD_COLOR); if (image.empty()) { cout << "could not find the image resource..." << std::endl; return -1; } namedWindow("input", CV_WINDOW_AUTOSIZE); imshow("input", image); Mat gray_image; gray_image.create(image.size(),IMREAD_GRAYSCALE); int height = image.rows; int width = image.cols; for (int row = 0; row < height; row++) { for (int col = 0; col < width; col++) { int b = image.at<Vec3b>(row, col)[0]; int g = image.at<Vec3b>(row, col)[1]; int r = image.at<Vec3b>(row, col)[2]; int gray =0.114*b +0.587*g + 0.299*r ; // int gray =(b +g + r)/3 ; gray_image.at<uchar>(row, col) = gray; } } namedWindow("output", CV_WINDOW_AUTOSIZE); imshow("output", gray_image); waitKey(0); return 0; }
效果图:
二、图像灰度值反转:
图像的反转原理很简单,每个像素的色度的范围为(0-255)彩色为r,g,b,三个通道。灰度图像只有一个通道即黑白(0-255)。
颜色的反转:就是用255-原来的像素值=新的像素值 从而达到像素翻转的效果。
与上面就一行代码变化:替换就行了
代码如下:
#include <opencv2/core/core.hpp> #include <opencv2/imgcodecs.hpp> #include <opencv2/opencv.hpp> #include <opencv2/highgui/highgui.hpp> #include <iostream> using namespace cv; using namespace std; int main(int argc, char** args) { Mat image = imread("L:/4.jpg", IMREAD_COLOR); if (image.empty()) { cout << "could not find the image resource..." << std::endl; return -1; } namedWindow("input", CV_WINDOW_AUTOSIZE); imshow("input", image); Mat gray_image1; gray_image1.create(image.size(), IMREAD_GRAYSCALE); int height = image.rows; int width = image.cols; for (int row = 0; row < height; row++) { for (int col = 0; col < width; col++) { int b = image.at<Vec3b>(row, col)[0]; int g = image.at<Vec3b>(row, col)[1]; int r = image.at<Vec3b>(row, col)[2]; int gray = (b + g + r) / 3; gray_image1.at<uchar>(row, col) =255 - gray; } } namedWindow("output1", CV_WINDOW_AUTOSIZE); imshow("output1", gray_image1); waitKey(0); return 0; }
效果:
反彩色图像原理一样这里就不在展示了。
二、图像的对比度亮度调整:
这里首先给出一个公式:F= α(f) + β f为原像素值, F为变化后的像素值。
其中 α控制的为对比度,β控制亮度。
核心操作:
彩色
灰度
原代码如下
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
int main(int argc, char** argv) {
Mat src, dst;
src = imread("L:/4.jpg");
if (!src.data) {
printf("could not load image...\n");
return -1;
}
char input_win[] = "input image"; //定义一个变量input_win来表示窗口名
//cvtColor(src, src, CV_BGR2GRAY);
namedWindow(input_win, CV_WINDOW_AUTOSIZE);
imshow(input_win, src);
// contrast and brigthtness changes
int height = src.rows;
int width = src.cols;
dst = Mat::zeros(src.size(), src.type());
float alpha = 1.0;
float beta = 100;
Mat m1;
src.convertTo(m1, CV_32F); //强制转化浮点型,提高精度
for (int row = 0; row < height; row++) {
for (int col = 0; col < width; col++) {
if (src.channels() == 3) {
float b = m1.at<Vec3f>(row, col)[0];// blue
float g = m1.at<Vec3f>(row, col)[1]; // green
float r = m1.at<Vec3f>(row, col)[2]; // red
// output
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);
}
else if (src.channels() == 1) {
float v = src.at<uchar>(row, col);
dst.at<uchar>(row, col) = saturate_cast<uchar>(v*alpha + beta);
}
}
}
char output_title[] = "contrast and brightness change demo";
namedWindow(output_title, CV_WINDOW_AUTOSIZE);
imshow(output_title, dst);
waitKey(0);
return 0;
}
效果
α=1,β=100, 整体提高亮度。
α=1.8,β=0,提高图片的对比度
三、两张图片的适应叠加
f0表示图一的像素,f1表示图二的像素。
核心操作:
addWeight API (图像1, α, 图像2, 1-α, 0.0, 生成图像 )
原代码如下:
#include <opencv2/opencv.hpp> #include <iostream> using namespace std; using namespace cv; int main(int argc, char** argv) { Mat src1, src2, dst; src1 = imread("L:/opencv_picture/3.jpg"); src2 = imread("L:/opencv_picture/4.jpg"); if (!src1.data) { cout << "could not load image Linux Logo..." << endl; return -1; } if (!src2.data) { cout << "could not load image WIN7 Logo..." << endl; return -1; } double alpha = 0.5; if (src1.rows == src2.rows && src1.cols == src2.cols && src1.type() == src2.type()) { addWeighted(src1, alpha, src2, (1.0 - alpha), 0.0, dst); // multiply(src1, src2, dst, 1.0); imshow("linuxlogo", src1); imshow("win7logo", src2); namedWindow("blend demo", CV_WINDOW_AUTOSIZE); imshow("blend demo", dst); } else { printf("could not blend images , the size of images is not same...\n"); return -1; } waitKey(0); return 0; }
效果: