6.5,漫水填充
#include<opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include<iostream>
using namespace cv;
using namespace std;
#include <opencv2/imgproc/imgproc.hpp>
//全局变量的声明
Mat g_srcImage, g_dstImage,g_grayImage,g_maskImage;
int g_nFillMode = 1;
int g_nLowDifference = 20, g_nUpDifference = 20;//负差最大值、正差最大值
int g_nConnectivity =4;//表示FloodFill函数标识符低八位的连通值
int g_bIsColor = true;
bool g_bUseMask=false;
int g_nNewMaskVal = 255;
//鼠标消息onMouse回调函数
static void onMouse(int event, int x, int y, int, void*)
{//鼠标左键没有按下便返回
if (event != EVENT_LBUTTONDOWN)
return;
Point seed = Point(x, y);
//空范围的漫水填充,此值设为0,否则设为全局的g_nLowDifference
int LowDifference = g_nFillMode == 0 ? 0 : g_nLowDifference;
//空范围的漫水填充,此值设为0,否则设为全局的g_nUpDifference
int UpDifference = g_nFillMode == 0 ? 0 : g_nUpDifference;
int flags = g_nConnectivity + (g_nNewMaskVal << 8) + (g_nFillMode ==
1 ? FLOODFILL_FIXED_RANGE : 0);
//随机生成bgr值
int b = (unsigned)theRNG() & 255;
int g = (unsigned)theRNG() & 255;
int r = (unsigned)theRNG() & 255;
Rect ccomp;
Scalar newVal = g_bIsColor ? Scalar(b, g, r) : Scalar(r*0.299 + g*0.587 +
b*0.114);//重绘区域像素的新值,若是彩色模式Scalar(b, g, r),若是灰度图
//选择Scalar(r*0.299 + g*0.587 +b*0.114)
Mat dst = g_bIsColor ? g_dstImage : g_grayImage;
int area;
if (g_bUseMask){
threshold(g_maskImage, g_maskImage, 1, 128, THRESH_BINARY);
area = floodFill(dst, g_maskImage, seed, newVal, &ccomp,
Scalar(LowDifference, LowDifference, LowDifference),
Scalar(UpDifference, UpDifference, UpDifference), flags);
imshow("mask", g_maskImage); }
else
{
area = floodFill(dst, seed, newVal, &ccomp,
Scalar(LowDifference, LowDifference, LowDifference),
Scalar(UpDifference, UpDifference, UpDifference), flags);
imshow("mask", g_maskImage);
}
imshow("效果图", dst);
cout << area << "个像素被重绘\n";
}
int main(int argc,char**argv)
{
g_srcImage = imread("dong.jpg");
if (!g_srcImage.data){ printf("读取错误\n"); return false; }
g_srcImage.copyTo(g_dstImage);
cvtColor(g_srcImage, g_srcImage, COLOR_BGR2GRAY);
g_maskImage.create(g_srcImage.rows + 2, g_srcImage.cols + 2, CV_8UC1);
namedWindow("效果图", WINDOW_AUTOSIZE);
createTrackbar("负差最大值", "效果图", &g_nLowDifference, 255, 0);
createTrackbar("正差最大值", "效果图", &g_nUpDifference, 255, 0);
setMouseCallback("效果图", onMouse, 0);//鼠标回调函数
while (1){
imshow("效果图", g_bIsColor ? g_dstImage : g_grayImage);
int c=waitKey(0);
//判断ESC是否按下
if ((c & 255) == 27)
{
cout << "程序退出\n";
break;
}
switch ((char)c)
{//如果1被按下,效果图在灰度图和彩色土之间切换
case'1':
if (g_bIsColor)
{
cout << "按下键盘1,切换彩色/灰度模式\n";
cvtColor(g_srcImage, g_grayImage, COLOR_BGR2GRAY);
g_maskImage = Scalar::all(0);
g_bIsColor = false;
}
else{
cout << "键盘1按下,切换彩色/灰度模式\ne";
g_srcImage.copyTo(g_dstImage);
g_maskImage = Scalar::all(0);
g_bIsColor = true;
}
break;
//如果键盘2按下,显示/隐藏掩膜窗口
case'2':
if (g_bUseMask)
{
destroyWindow("mask");
g_bUseMask = false;
}
else
{
namedWindow("mask", 0);
g_maskImage = Scalar::all(0);
imshow("mask", g_maskImage);
g_bUseMask = true;
}
break;
//如果键盘3按下,恢复原始图像
case'3':
cout << "按键3按下,恢复原图像\n";
g_srcImage.copyTo(g_dstImage);
cvtColor(g_dstImage, g_grayImage, COLOR_BGR2GRAY);
g_maskImage = Scalar::all(0);
break;
case'4':
cout << "按键4按下,使用空范围的漫水填充\n";
g_nFillMode = 0;
break;
case'5':
cout << "按键5按下,使用渐变、固定范围的漫水填充\n";
g_nFillMode = 1;
break;
case'6':
cout << "按键6按下,使用渐变、浮动范围的漫水填充\n";
g_nFillMode = 2;
break;
case'7':
cout << "按键7按下,操作标志符的低八位使用4位连接模式\n";
g_nConnectivity = 4;
break;
case'8':
cout << "按键8按下,操作标志符的低八位使用8位连接模式\n";
g_nConnectivity = 8;
break;
}
}
return 0;
}
程序执行结果如图:
掩膜:
6.6,图像金字塔与图片尺寸缩放:
#include<opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;
using namespace std;
#include <opencv2/imgproc/imgproc.hpp>
#define WINDOW_NAME "程序窗口"//窗口标题定义的宏
//全局变量的声明
Mat g_srcImage, g_dstImage,g_tempImage;
int main()
{
g_srcImage = imread("dong.jpg");
if (!g_srcImage.data){ printf("读取错误\n"); return false; }
namedWindow( WINDOW_NAME, WINDOW_AUTOSIZE );
imshow(WINDOW_NAME, g_srcImage);
//参数赋值
g_tempImage = g_srcImage;
g_dstImage = g_tempImage;
int key = 0;
while (1){
key=waitKey(9);
switch (key)
{//如果1被按下,效果图在灰度图和彩色土之间切换
case 27://按键ESC
return 0;
break;
case 'q'://按键q
return 0;
break;
case 'a'://按键A按下,调用pyrUp函数
pyrUp(g_tempImage, g_dstImage, Size(g_tempImage.cols * 2,
g_tempImage.rows * 2));
printf(">检测到按键A按下,进行基于pyrUp函数的图片放大\n");
break;
case 'w'://按键w按下,调用resize函数
resize(g_tempImage, g_dstImage, Size(g_tempImage.cols * 2,
g_tempImage.rows * 2));
printf(">检测到按键W按下,进行基于resize函数的图片放大\n");
break;
case '1'://按键1按下,调用resize函数
resize(g_tempImage, g_dstImage, Size(g_tempImage.cols * 2,
g_tempImage.rows * 2));
printf(">检测到按键1按下,进行基于resize函数的图片放大\n");
break;
case '3'://按键3按下,调用pyrUp函数
pyrUp(g_tempImage, g_dstImage, Size(g_tempImage.cols * 2,
g_tempImage.rows * 2));
printf(">检测到按键3按下,进行基于pyrUp函数的图片放大\n");
break;
case 'd':
pyrDown(g_tempImage, g_dstImage, Size(g_tempImage.cols / 2,
g_tempImage.rows / 2));
printf(">检测到按键D按下,进行基于pyrDown函数的图片缩小\n");
break;
case 's':
resize(g_tempImage, g_dstImage, Size(g_tempImage.cols / 2,
g_tempImage.rows / 2));
printf(">检测到按键S按下,进行基于resize函数的图片缩小\n");
break;
case '2':
resize(g_tempImage, g_dstImage, Size(g_tempImage.cols / 2,
g_tempImage.rows / 2));
printf(">检测到按键2按下,进行基于resize函数的图片缩小\n");
break;
case '4':
pyrDown(g_tempImage, g_dstImage, Size(g_tempImage.cols / 2,
g_tempImage.rows / 2));
printf(">检测到按键4按下,进行基于pyrDown函数的图片缩小\n");
break;
}
imshow(WINDOW_NAME, g_dstImage);
g_tempImage = g_dstImage;
}
return 0;
}
程序执行结果如图:
6.7:基本阈值操作:
#include<opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;
using namespace std;
#include <iostream>
#include <opencv2/imgproc/imgproc.hpp>
#define WINDOW_NAME "程序窗口"//窗口标题定义的宏
//全局变量的声明
Mat g_srcImage, g_dstImage,g_grayImage;
int g_nThresholdValue = 100;
int g_nThresholdType = 3;
static void ShowHelpText();//输出帮助文字
void on_Threshold(int, void*);//回调函数
int main()
{
g_srcImage = imread("dong.jpg");
if (!g_srcImage.data){ printf("读取错误\n"); return false; }
cvtColor(g_srcImage, g_grayImage, COLOR_RGB2GRAY);
namedWindow( WINDOW_NAME, WINDOW_AUTOSIZE );
createTrackbar("模式", WINDOW_NAME, &g_nThresholdType,4,on_Threshold);
createTrackbar("参数值", WINDOW_NAME, &g_nThresholdValue, 255, on_Threshold);
on_Threshold(0, 0 );
while (1){
int key;
key = waitKey(20);
if ((char)key == 27){ break; }
}
}
void on_Threshold(int, void*)
{
threshold(g_grayImage, g_dstImage,g_nThresholdValue, 255, g_nThresholdType);
imshow(WINDOW_NAME, g_dstImage);
}
程序执行结果如图: