通过设定Scalar算子的算术运算操作
void QuickDemo::operator_demo(Mat& img)
{
Mat dst;
dst = img + Scalar(50, 50, 50);
dst = img - Scalar(50, 50, 50);
Mat drawer = Mat::zeros(img.size(), img.type());
drawer = Scalar(2, 2, 2);
multiply(drawer, img, dst);
imshow("src", img);
imshow("dst", dst);
}
通过这个例子我们可以知道,Scalar实际上是一种算子,可以对每一个像素点进行运算,运算值是灰度值. 运算用法编写的demo
void QuickDemo::operator_demo(Mat& img)
{
Mat dst;
dst = img + Scalar(50, 50, 50);
dst = img - Scalar(50, 50, 50);
dst = img / Scalar(2, 2, 2);
dst = img * Scalar(2, 2, 2);
int n = img.rows;
int m = img.cols;
int dims = img.channels();
Mat drawer = Mat::zeros(img.size(),img.type());
drawer = Scalar(50, 50, 50);
Mat dst = drawer.clone();
if (dims == 1)
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
dst.at<uchar>(i, j) = saturate_cast<uchar>(drawer.at<uchar>(i,j)+img.at<uchar>(i,j));
}
}
}
if (dims == 3)
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
Vec3b p1 = img.at<Vec3b>(i, j);
Vec3b p2 = drawer.at<Vec3b>(i, j);
dst.at<Vec3b>(i, j) = saturate_cast<uchar>(p1[0] + p2[0]);
dst.at<Vec3b>(i, j) = saturate_cast<uchar>(p1[1] + p2[1]);
dst.at<Vec3b>(i, j) = saturate_cast<uchar>(p1[2] + p2[2]);
}
}
}
Mat dst;
Mat drawer = Mat::zeros(img.size(), img.type());
drawer = Scalar(2, 2, 2);
multiply(drawer, img, dst);
cv::add(img, drawer, dst);
cv::subtract(img, drawer, dst);
cv::divide(img, drawer, dst);
cv::multiply(img, drawer, dst);
imshow("src", img);
imshow("dst", dst);
}
滚动条演示调节亮度等参数(OpencvGUI)
demo01初体验
Mat src, dst, m;
int lightness = 50;
static void on_track(int , void *)
{
m = Scalar(lightness, lightness, lightness);
cv::add(src, m, dst);
imshow("亮度调节", dst);
}
void QuickDemo::track_bar_demo(Mat& img)
{
namedWindow("亮度调整", WINDOW_AUTOSIZE);
int maxval = 100;
src = img.clone();
m = Mat::zeros(img.size(), img.type());
dst = Mat::zeros(img.size(), img.type());
createTrackbar("value_bar", "亮度调整", &lightness,maxval,on_track);
on_track(50, 0);
}
这里对回调函数需要解释一下,意思是当产生了一个事件之后,系统捕获到了这个事件,就会把参数传回到callback函数中去。 总结来说:实现这个功能,首先需要一个窗口来承载trackerbar,然后设定好画布算子,然后编写回调函数,把传回来的参数利用起来即可。
优化版本,传递变量
static void on_track(int modify_value, void* userdata)
{
Mat img = *(Mat*) userdata;
Mat m = Mat::zeros(img.size(), img.type());
Mat src = img.clone();
Mat dst;
m = Scalar(modify_value, modify_value, modify_value);
cv::add(src , m, dst);
imshow("亮度调整", dst);
}
void QuickDemo::track_bar_demo(Mat& img)
{
namedWindow("亮度调整", WINDOW_AUTOSIZE);
int maxval = 100;
int lightness = 50;
createTrackbar("value_bar", "亮度调整", &lightness,maxval,on_track,(void*)(&img));
on_track(50, &img);
}
如果需要同时调节亮度和对比度的话,就需要同时使用两个trackbar,同时合成两幅图像,要用addweight这个api
static void on_light(int modify_value, void* userdata)
{
Mat img = *((Mat*) userdata);
Mat m = Mat::zeros(img.size(), img.type());
Mat src = img.clone();
Mat dst= Mat::zeros(img.size(), img.type());
addWeighted(src, 1.0, m, 0.0, modify_value, dst);
imshow("亮度与对比度调整", dst);
}
static void on_contract(int modify_value, void* userdata)
{
Mat img = *((Mat*)userdata);
Mat m = Mat::zeros(img.size(), img.type());
Mat src = img.clone();
Mat dst= Mat::zeros(img.size(), img.type());
double contract_val = modify_value / 100.0;
addWeighted(src, contract_val, m, 0.0,0,dst);
imshow("亮度与对比度调整", dst);
}
void QuickDemo::track_bar_demo(Mat& img)
{
namedWindow("亮度与对比度调整", WINDOW_AUTOSIZE);
int maxval_light = 100,lightness=50;
int maxval_contract =200, contractness = 120;
createTrackbar("light_bar", "亮度与对比度调整", &lightness, maxval_light,on_light,(void*)(&img));
createTrackbar("contract_bar", "亮度与对比度调整", &contractness, maxval_contract, on_contract, (void*)(&img));
on_light(50, &img);
}
总结一下滚动条,其实就是为不同的滚动条的数据提供不同的方法,如果是多种参数共同调节的话就要使用addWeight来实现。 重点是要学到addWeight这个函数的用法:改变亮度,我们通过改变加的gamma来改变Mat数组内每一个点的灰度值 改变对比度,那就是通过alpha的值来改变,改变比值,从而产生对比的这一种效果。
简单键盘操作的应用
void QuickDemo::key_demo(Mat& img)
{
char c;
Mat dst = Mat::zeros(img.size(), img.type());
while (1)
{
c = waitKey(100);
if (c == 27)
{
break;
}
else if (c == '1')
{
cvtColor(img, dst, COLOR_BGR2HSV);
}
else if (c == '2')
{
cvtColor(img, dst, COLOR_BGR2GRAY);
}
imshow("dst", dst);
}
}
三行代码,让opencv给我创建了十九个颜色表(
applyColorMap
void QuickDemo::color_style_demo(Mat& img)
{
int colormap[] = {
COLORMAP_AUTUMN,
COLORMAP_BONE,
COLORMAP_JET,
COLORMAP_WINTER,
COLORMAP_RAINBOW,
COLORMAP_OCEAN,
COLORMAP_SUMMER,
COLORMAP_SPRING,
COLORMAP_COOL,
COLORMAP_HSV,
COLORMAP_PINK,
COLORMAP_HOT,
};
Mat dst;
int index = 0;
while (1)
{
char c;
c = waitKey(200);
if (c == 27)
{
break;
}
applyColorMap(img, dst, colormap[(index%11)]);
index++;
imshow("dst", dst);
}
}
图像像素的逻辑操作(位操作)
基本是就是对图像中的每一个像素点的灰度值进行和与或异或操作。
void QuickDemo::bitwises_demo(Mat& img)
{
Mat drawer1 = Mat::zeros(Size(256, 256), CV_8UC3);
Mat drawer2 = Mat::zeros(Size(256, 256), CV_8UC3);
rectangle(drawer1, Rect(100, 100, 100, 100), Scalar(255, 255, 0), -1, LINE_8,0);
rectangle(drawer2, Rect(150, 150, 80, 80), Scalar(0, 255,255), -1, LINE_8,0);
imshow("drawer1", drawer1);
imshow("drawer2", drawer2);
Mat dst;
bitwise_and(drawer1,drawer2,dst);
bitwise_or(drawer1, drawer2, dst);
bitwise_not(drawer1, dst);
imshow("dst", dst);
}
|