图像对比度增强方法的问题。基本上我们要为图像的每个像素应用以下公式:
I(i,j) = 5 * I(i,j) – [ I(i-1,j) + I(i+1,j) + I(i,j-1) + I(i,j+1)],
#include
#include
#include
#include
using namespace std;
using namespace cv;
int main(int argc, char* argb[])
{
Mat I = imread("../data/test2.jpg");
if (I.empty()) {
cout << "cannot read the image!" << endl;
return 0;
}
Mat K;
Mat kernel = (Mat_<char>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
filter2D(I, K, I.depth(), kernel);
imshow("original", I);
imshow("sharpen", K);
waitKey(0);
return 0;
}
#include
#include
#include
#include
using namespace std;
using namespace cv;
static void help(char* progName)
{
cout << endl
<< "This program shows how to filter images with mask: the write it yourself and the"
<< "filter2d way. " << endl
<< "Usage:" << endl
<< progName << " [image_path -- default lena.jpg] [G -- grayscale] " << endl << endl;
}
void Sharpen(const Mat& myImage, Mat& Result);
int main(int argc, char* argv[])
{
help(argv[0]);
const char* filename = argc >= 2 ? argv[1] : "../data/test2.jpg";
Mat src, dst0, dst1;
if (argc >= 3 && !strcmp("G", argv[2]))
src = imread(samples::findFile(filename), IMREAD_GRAYSCALE);
else
src = imread(samples::findFile(filename), IMREAD_COLOR);
if (src.empty())
{
cerr << "Can't open image [" << filename << "]" << endl;
return EXIT_FAILURE;
}
namedWindow("Input", WINDOW_AUTOSIZE); //创建窗口
namedWindow("Output1", WINDOW_AUTOSIZE);//创建窗口
namedWindow("Output2", WINDOW_AUTOSIZE);//创建窗口
imshow("Input", src);//显示图像
//方法1: 自己写的函数
double t = (double)getTickCount();//计时开始
Sharpen(src, dst0);
t = ((double)getTickCount() - t) / getTickFrequency();//计算时间
cout << "Hand written function, 自己写的代码耗时: " << t << endl;//输出时间
imshow("Output1", dst0);//显示图像
//方法2: filter2D函数
Mat kernel = (Mat_<char>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
t = (double)getTickCount();//计时开始
filter2D(src, dst1, src.depth(), kernel);
t = ((double)getTickCount() - t) / getTickFrequency();//计算时间
cout << "Built-in filter2D , filter2D耗时: " << t << endl;//输出时间
imshow("Output2", dst1);//显示图像
waitKey();
return EXIT_SUCCESS;
}
void Sharpen(const Mat& myImage, Mat& Result)
{
CV_Assert(myImage.depth() == CV_8U); // accept only uchar images
//创建通道
const int nChannels = myImage.channels();
Result.create(myImage.size(), myImage.type());
//基本方法循环
for (int j = 1; j < myImage.rows - 1; ++j)
{
const uchar* previous = myImage.ptr<uchar>(j - 1);
const uchar* current = myImage.ptr<uchar>(j);
const uchar* next = myImage.ptr<uchar>(j + 1);
uchar* output = Result.ptr<uchar>(j);
for (int i = nChannels; i < nChannels * (myImage.cols - 1); ++i)
{
*output++ = saturate_cast<uchar>(5 * current[i]
- current[i - nChannels] - current[i + nChannels] - previous[i] - next[i]);
}
}
//目标像素点周围的四个像素点
Result.row(0).setTo(Scalar(0));
Result.row(Result.rows - 1).setTo(Scalar(0));
Result.col(0).setTo(Scalar(0));
Result.col(Result.cols - 1).setTo(Scalar(0));
}
执行结果:
Hand written function, 自己写的代码耗时: 0.0022542
Built-in filter2D , filter2D耗时: 0.0005542
还可以使用以下方式进行:像素之间的 加、减、乘法
saturateResult.at(row, col)[0] = saturate_cast(b1 * b2);
saturateResult.at(row, col)[1] = saturate_cast(g1 * g2);
saturateResult.at(row, col)[2] = saturate_cast(r1 * r2);
#include
#include
#include
#include
using namespace std;
using namespace cv;
int main(int argv, char** argc)
{
Mat src1 = imread("../data/test7.jpg");
Mat src2 = imread("../data/test8.jpg");
if (src1.empty() || src2.empty())
{
printf("Could not load image src1 or src2...\n");
return -1;
}
Mat addResult = Mat::zeros(src1.size(), src1.type());
add(src1, src2, addResult);
imshow("addResult 加", addResult);
Mat subResult = Mat::zeros(src1.size(), src1.type());
subtract(src1, src2, subResult);
imshow("subResult 减", subResult);
Mat mulResult = Mat::zeros(src1.size(), src1.type());
multiply(src1, src2, mulResult);
imshow("mulResult 乘", mulResult);
Mat divResult = Mat::zeros(src1.size(), src1.type());
divide(src1, src2, divResult);
imshow("divResult 除", divResult);
int b1 = 0, g1 = 0, r1 = 0;
int b2 = 0, g2 = 0, r2 = 0;
//int b = 0, g = 0, r = 0;
int height = src1.rows;
int width = src1.cols;
Mat saturateResult = Mat::zeros(src1.size(), src1.type());
for (int row = 0; row < height; row++) {
for (int col = 0; col < width; col++) {
b1 = src1.at<Vec3b>(row, col)[0];
g1 = src1.at<Vec3b>(row, col)[1];
r1 = src1.at<Vec3b>(row, col)[2];
b2 = src2.at<Vec3b>(row, col)[0];
g2 = src2.at<Vec3b>(row, col)[1];
r2 = src2.at<Vec3b>(row, col)[2];
saturateResult.at<Vec3b>(row, col)[0] = saturate_cast<uchar>(b1 + b2);
saturateResult.at<Vec3b>(row, col)[1] = saturate_cast<uchar>(g1 + g2);
saturateResult.at<Vec3b>(row, col)[2] = saturate_cast<uchar>(r1 + r2);
}
}
imshow("saturateResult 相加", saturateResult);
for (int row = 0; row < height; row++) {
for (int col = 0; col < width; col++) {
b1 = src1.at<Vec3b>(row, col)[0];
g1 = src1.at<Vec3b>(row, col)[1];
r1 = src1.at<Vec3b>(row, col)[2];
b2 = src2.at<Vec3b>(row, col)[0];
g2 = src2.at<Vec3b>(row, col)[1];
r2 = src2.at<Vec3b>(row, col)[2];
saturateResult.at<Vec3b>(row, col)[0] = saturate_cast<uchar>(b1 * b2);
saturateResult.at<Vec3b>(row, col)[1] = saturate_cast<uchar>(g1 * g2);
saturateResult.at<Vec3b>(row, col)[2] = saturate_cast<uchar>(r1 * r2);
}
}
imshow("saturateResult 相乘", saturateResult);
waitKey(0);
return 0;
}
执行结果:
#include "opencv2\opencv.hpp"
#include
using namespace std;
using namespace cv;
int main(int argc, char* argv[])
{
//创建图片1
Mat src1 = Mat::zeros(Size(400, 400), CV_8UC3);
Rect rect(100, 100, 100, 100);
src1(rect) = Scalar(0, 0, 255);//bgr
imshow("input1", src1);
printf("创建第一张图片...\n");
//创建图片2
Mat src2 = Mat::zeros(Size(400, 400), CV_8UC3);
rect.x = 150;
rect.y = 150;
src2(rect) = Scalar(0, 0, 255);//bgr
imshow("input2", src2);
printf("创建第二张图片...\n");
//取反操作
Mat src = imread("../data/test2.jpg");
imshow("input", src);
Mat dst;
bitwise_not(src, dst);
//逻辑操作
Mat dst1, dst2, dst3;
bitwise_and(src1, src2, dst1);
bitwise_or(src1, src2, dst2);
bitwise_xor(src1, src2, dst3);
//结果显示
imshow("取反操作", dst);
imshow("逻辑与", dst1);
imshow("逻辑或", dst2);
imshow("逻辑异或", dst3);
waitKey(0);
return 0;
}