之前有一段时间发现在图片上添加滑动条的时候在运行的时会发生没有出现滑动条的情况,也是百思不得其姐。
后来发现自己犯了一个很蠢的错误,记录在此以防再犯。
不良的习惯
之前在写程序的时候由于在显示图像的时候因为图像过大而不能显示完全或者图片篇需要手动修改其大小,因此总是在imshow()函数显示图片前加入窗口函数namedWindow();也正是这个自以为优秀的习惯为我后面的程序付出了较大的代价。不过吃一堑长一智,也算涨了次教训。
因为对于计算机而言程序是从上往下执行,计算机不会像人类一样知道辩证考虑先后顺序。因此在添加窗口函数createTrackbar( )时一定要在创建滑动块的前面添加窗口函数。
以下为坏习惯在创建滑动块后面添加窗口函数的后果。
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace cv;
//原图,原图的灰度,目标图
Mat g_srcImage, g_srcGrayImage,g_dstImage;
//Canny边缘检测相关变量
Mat g_cannyDetectedEdges;
int g_cannyLowThreshold=1;//TrackBar位置参数
static void ShowHelpText( );
static void on_Canny(int, void*);//Canny边缘检测窗口滚动条的回调函数
int main( int argc, char** argv )
{
//改变console字体颜色
system("color 2F");
//载入原图
g_srcImage = imread("芷若.png");
if( !g_srcImage.data ) { printf("Oh,no,读取srcImage错误~! \n"); return false; }
//显示原始图
namedWindow("【原始图】",WINDOW_NORMAL);
imshow("【原始图】", g_srcImage);
// 创建与src同类型和大小的矩阵(dst)
g_dstImage.create( g_srcImage.size(), g_srcImage.type() );
// 将原图像转换为灰度图像
cvtColor( g_srcImage, g_srcGrayImage, CV_BGR2GRAY );
// 创建trackbar
createTrackbar( "参数值:", "【效果图】Canny边缘检测", &g_cannyLowThreshold, 120, on_Canny );
// 调用回调函数
on_Canny(0, 0);
//轮询获取按键信息,若按下Q,程序退出
while((char(waitKey(1)) != 'q')) {}
return 0;
}
// 描述:Canny边缘检测窗口滚动条的回调函数
void on_Canny(int, void*)
{
// 先使用 3x3内核来降噪
blur( g_srcGrayImage, g_cannyDetectedEdges, Size(3,3) );
// 运行我们的Canny算子
Canny( g_cannyDetectedEdges, g_cannyDetectedEdges, g_cannyLowThreshold, g_cannyLowThreshold*3, 3 );
//先将g_dstImage内的所有元素设置为0
g_dstImage = Scalar::all(0);
//使用Canny算子输出的边缘图g_cannyDetectedEdges作为掩码,来将原图g_srcImage拷到目标图g_dstImage中
g_srcImage.copyTo( g_dstImage, g_cannyDetectedEdges);
//显示效果图
namedWindow("【效果图】Canny边缘检测",WINDOW_NORMAL);
imshow( "【效果图】Canny边缘检测", g_dstImage );
}
注意这里的窗口函数在createTrackbar( );之后
namedWindow("【效果图】Canny边缘检测",WINDOW_NORMAL);
imshow( “【效果图】Canny边缘检测”, g_dstImage );
结果如下
以下为正确创建窗口函数的运行代码
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace cv;
//原图,原图的灰度,目标图
Mat g_srcImage, g_srcGrayImage,g_dstImage;
//Canny边缘检测相关变量
Mat g_cannyDetectedEdges;
int g_cannyLowThreshold=1;//TrackBar位置参数
static void ShowHelpText( );
static void on_Canny(int, void*);//Canny边缘检测窗口滚动条的回调函数
int main( int argc, char** argv )
{
//改变console字体颜色
system("color 2F");
//载入原图
g_srcImage = imread("芷若.png");
if( !g_srcImage.data ) { printf("Oh,no,读取srcImage错误~! \n"); return false; }
//显示原始图
namedWindow("【原始图】",WINDOW_NORMAL);
imshow("【原始图】", g_srcImage);
// 创建与src同类型和大小的矩阵(dst)
g_dstImage.create( g_srcImage.size(), g_srcImage.type() );
// 将原图像转换为灰度图像
cvtColor( g_srcImage, g_srcGrayImage, CV_BGR2GRAY );
// 创建trackbar
namedWindow("【效果图】Canny边缘检测",WINDOW_NORMAL);
createTrackbar( "参数值:", "【效果图】Canny边缘检测", &g_cannyLowThreshold, 120, on_Canny );
// 调用回调函数
on_Canny(0, 0);
//轮询获取按键信息,若按下Q,程序退出
while((char(waitKey(1)) != 'q')) {}
return 0;
}
// 描述:Canny边缘检测窗口滚动条的回调函数
void on_Canny(int, void*)
{
// 先使用 3x3内核来降噪
blur( g_srcGrayImage, g_cannyDetectedEdges, Size(3,3) );
// 运行我们的Canny算子
Canny( g_cannyDetectedEdges, g_cannyDetectedEdges, g_cannyLowThreshold, g_cannyLowThreshold*3, 3 );
//先将g_dstImage内的所有元素设置为0
g_dstImage = Scalar::all(0);
//使用Canny算子输出的边缘图g_cannyDetectedEdges作为掩码,来将原图g_srcImage拷到目标图g_dstImage中
g_srcImage.copyTo( g_dstImage, g_cannyDetectedEdges);
//显示效果图
imshow( "【效果图】Canny边缘检测", g_dstImage );
}
注意这里的窗口函数在createTrackbar( );之前
namedWindow("【效果图】Canny边缘检测",WINDOW_NORMAL);
createTrackbar( “参数值:”, “【效果图】Canny边缘检测”, &g_cannyLowThreshold, 120, on_Canny );
结果如下
1354933