opencv 能读取到图片,但是显示灰色

今天接着在看canny边缘检测,却又遇到了问题,用的VS2017 Opencv 3.1.0 ,就是opencv 能读取到图片,但是显示灰色的一个窗口,且一闪而过。
下面是我出现问题的代码:

未运行成功的代码:


//#include "stdafx.h"         //这个是加载MFC的头文件用的,需要自己编写,不编写的话,注释即可
#include "cv.h"               //  OpenCV 文件
#include "cvaux.h"
#include "cxcore.h"
#include "opencv2/opencv.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp" 
#include 
#include 

 using namespace cv;
 using namespace std;

//-----------------------------------【main( )函数】--------------------------------------------
//      描述:控制台应用程序的入口函数,我们的程序从这里开始
//-------------------------------------------------------------------------------------------------
int main()
{
    //【0】载入原始图  
    Mat srcImage = imread("1.jpg");


     imshow("yuanshitu", srcImage);

    Mat dstImage, edge, grayImage;  //参数定义

  //【1】创建与src同类型和大小的矩阵(dst)
    dstImage.create(srcImage.size(), srcImage.type());

    cvtColor(srcImage, grayImage, COLOR_BGR2GRAY);

    //【3】先用使用 3x3内核来降噪
    blur(grayImage, edge, Size(3, 3));

    //【4】运行Canny算子
    Canny(edge, edge, 3, 9, 3);

    //【5】显示效果图 
    imshow("xiaoguotu", edge);

    waitKey(0);

    return 0;
}

然后我上网搜了一下图片显示灰色是什么原因,大多数说是因为你图片没有读取到,图片路径不对等等,于是我加入测试代码,看看到底图片有没有读取成功,
测试代码如下:

/************测试图片是否读取成功********************/     
    /* if (!srcImage.empty())
     {
         std::cout << "can load picture" << "\n";
         return -1;
     }*/
/*************************************************/

将该段代码放到 Mat srcImage = imread(“1.jpg”);之后。
然后运行,dos窗口显示读取成功,这就让我很困惑。
但是之后我添加了一句代码,竟然成功了,如下图

解决办法是,我在 “imshow(“yuanshitu”, srcImage);”语句前面加了“namedWindow(“yuanshitu”, 1);”这句代码,就成功了。网上查了这两个函数的作用,如下:

1.namedWindow函数

顾名思义,namedWindow函数,用于创建一个窗口。函数原型是这样的:

void namedWindow(const string& winname,int flags=WINDOW_AUTOSIZE );
第一个参数,const string&型的name,即填被用作窗口的标识符的窗口名称。

第二个参数,int 类型的flags ,窗口的标识,可以填如下的值:

WINDOW_NORMAL设置了这个值,用户便可以改变窗口的大小(没有限制)
WINDOW_AUTOSIZE如果设置了这个值,窗口大小会自动调整以适应所显示的图像,并且不能手动改变窗口大小。
WINDOW_OPENGL 如果设置了这个值的话,窗口创建的时候便会支持OpenGL。

函数剖析:

首先需要注意的是,它有默认值WINDOW_AUTOSIZE,所以,一般情况下,这个函数我们填一个变量就行了。

namedWindow函数的作用是,通过指定的名字,创建一个可以作为图像和进度条的容器窗口。如果具有相同名称的窗口已经存在,则函数不做任何事情。

我们可以调用destroyWindow()或者destroyAllWindows()函数来关闭窗口,并取消之前分配的与窗口相关的所有内存空间。

但话是这样说,其实对于代码量不大的简单小程序来说,我们完全没有必要手动调用上述的destroyWindow()或者destroyAllWindows()函数,因为在退出时,所有的资源和应用程序的窗口会被操作系统会自动关闭。

2.imshow函数

在指定的窗口中显示一幅图像。

void imshow(const string& winname, InputArray mat);
■ 第一个参数,const string&类型的winname,填需要显示的窗口标识名称。

■ 第二个参数,InputArray 类型的mat,填需要显示的图像。

imshow 函数详解:

imshow 函数用于在指定的窗口中显示图像。如果窗口是用CV_WINDOW_AUTOSIZE(默认值)标志创建的,那么显示图像原始大小。否则,将图像进行缩放以适合窗口。而imshow 函数缩放图像,取决于图像的深度:

如果载入的图像是8位无符号类型(8-bit unsigned),就显示图像本来的样子。
如果图像是16位无符号类型(16-bit unsigned)或32位整型(32-bit integer),便用像素值除以256。也就是说,值的范围是[0,255 x 256]映射到[0,255]。
如果图像是32位浮点型(32-bit floating-point),像素值便要乘以255。也就是说,该值的范围是[0,1]映射到[0,255]。

简单的说,就是namedWindow函数就是显示一个窗口,imshow函数显示图片,似乎大小和namedWindow函数显示的窗口一样大。而毛星云的那本书的参考代码却没有namedWindow函数,也不清楚具体情况是怎么样的,继续学习吧,希望到时候自己能理解,大家谁比较清楚,请指教,哈哈哈
最后把成功的代码贴出来:
成功代码:
 

//#include "stdafx.h"         //这个是加载MFC的头文件用的,需要自己编写,不编写的话,注释即可
#include "cv.h"               //  OpenCV 文件
#include "cvaux.h"
#include "cxcore.h"
#include "opencv2/opencv.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp" 
#include 
#include 

 using namespace cv;
 using namespace std;

//-----------------------------------【main( )函数】--------------------------------------------
//      描述:控制台应用程序的入口函数,我们的程序从这里开始
//-------------------------------------------------------------------------------------------------
int main()
{
    //【0】载入原始图  
    Mat srcImage = imread("1.jpg");

/************测试图片是否读取成功********************/     
    /* if (!srcImage.empty())
     {
         std::cout << "can load picture" << "\n";
         return -1;
     }*/
/*************************************************/
    namedWindow("yuanshitu", 1);
     imshow("yuanshitu", srcImage);

    Mat dstImage, edge, grayImage;  //参数定义

  //【1】创建与src同类型和大小的矩阵(dst)
    dstImage.create(srcImage.size(), srcImage.type());

    cvtColor(srcImage, grayImage, COLOR_BGR2GRAY);

    //【3】先用使用 3x3内核来降噪
    blur(grayImage, edge, Size(3, 3));

    //【4】运行Canny算子
    Canny(edge, edge, 3, 9, 3);

    //【5】显示效果图 
    imshow("xiaoguotu", edge);

    waitKey(0);

    return 0;
}

参考:

https://blog.csdn.net/mao_hui_fei/article/details/77478750

你可能感兴趣的:(opencv,opencv,能读取到图片,但是显示灰色)