【OpenCV】3rd-Canny边缘检测、打开摄像头

    xiaoxiao2021-11-19  56

    一、复杂的变换

    1、Canny边缘检测将输出写入一个单通道(灰度级)图像(p29)

    #include "cv.h" #include "highgui.h" IplImage* doCanny( IplImage* in, double lowThresh, double highThresh, double aperture) { if (in->nChannels != 1) return(0); // Canny only handles gray scale images IplImage* out = cvCreateImage( cvGetSize( in ), in->depth, //IPL_DEPTH_8U, 1); cvCanny( in, out, lowThresh, highThresh, aperture ); return( out ); }; int main( int argc, char** argv ) { IplImage* img_rgb = cvLoadImage( argv[1] ); IplImage* img_gry = cvCreateImage( cvSize( img_rgb->width,img_rgb->height ), img_rgb->depth, 1); cvCvtColor(img_rgb, img_gry ,CV_BGR2GRAY); cvNamedWindow("Example Gray", CV_WINDOW_AUTOSIZE ); cvNamedWindow("Example Canny", CV_WINDOW_AUTOSIZE ); cvShowImage("Example Gray", img_gry ); IplImage* img_cny = doCanny( img_gry, 10, 100, 3 ); cvShowImage("Example Canny", img_cny ); cvWaitKey(0); cvReleaseImage( &img_rgb); cvReleaseImage( &img_gry); cvReleaseImage( &img_cny); cvDestroyWindow("Example Gray"); cvDestroyWindow("Example Canny"); }

    前面的实现使更加容易进行一些连续的变换 IplImage* doCanny( IplImage* in, double lowThresh, double highThresh, double aperture) { if (in->nChannels != 1) return(0); // Canny only handles gray scale images IplImage* out = cvCreateImage( cvGetSize( in ), in->depth, //IPL_DEPTH_8U, 1); cvCanny( in, out, lowThresh, highThresh, aperture ); return( out ); };·· 如下例,可以简单地操作组合。


    2、进行两次缩放处理与边缘检测(p29)

    IplImage* img_pyr = doPyrDown( img_gry, IPL_GAUSSIAN_5x5 ); IplImage* img_pyr2 = doPyrDown( img_pyr, IPL_GAUSSIAN_5x5 ); IplImage* img_cny = doCanny( img_pyr2, 10, 100, 3 ); ... cvReleaseImage( &img_pyr); cvReleaseImage( &img_pyr2); cvReleaseImage( &img_cny); 以下是完整程序:

    #include "cv.h" #include "highgui.h" IplImage* doCanny( IplImage* in, double lowThresh, double highThresh, double aperture) { IplImage* out = cvCreateImage( cvGetSize( in ), in->depth, //IPL_DEPTH_8U, 1); cvCanny( in, out, lowThresh, highThresh, aperture ); return( out ); }; IplImage* doPyrDown( IplImage* in, int filter = IPL_GAUSSIAN_5x5) { // Best to make sure input image is divisible by two. // assert( in->width%2 == 0 && in->height%2 == 0 ); IplImage* out = cvCreateImage( cvSize( in->width/2, in->height/2 ), in->depth, in->nChannels ); cvPyrDown( in, out ); return( out ); }; int main( int argc, char** argv ) { IplImage* img_rgb = cvLoadImage( argv[1] ); IplImage* img_gry = cvCreateImage( cvSize( img_rgb->width,img_rgb->height ), img_rgb->depth, 1); cvCvtColor(img_rgb, img_gry ,CV_BGR2GRAY); IplImage* img_pyr = doPyrDown( img_gry, IPL_GAUSSIAN_5x5 ); IplImage* img_pyr2 = doPyrDown( img_pyr, IPL_GAUSSIAN_5x5 ); IplImage* img_cny = doCanny( img_pyr2, 10, 100, 3 ); cvNamedWindow("Example Gray", CV_WINDOW_AUTOSIZE ); cvNamedWindow("Example Pyr", CV_WINDOW_AUTOSIZE ); cvNamedWindow("Example Canny", CV_WINDOW_AUTOSIZE ); cvShowImage("Example Gray", img_gry ); cvShowImage("Example Pyr", img_pyr2 ); cvShowImage("Example Canny", img_cny ); cvWaitKey(0); cvReleaseImage( &img_rgb); cvReleaseImage( &img_gry); cvReleaseImage( &img_pyr); cvReleaseImage( &img_pyr2); cvReleaseImage( &img_cny); cvDestroyWindow("Example Gray"); cvDestroyWindow("Example Pyr"); cvDestroyWindow("Example Canny"); }

    3、自清理模式(p30)

    通过每个独立阶段释放内存来简化上例中图像处理流程: out = doPyrDown( out ); out = doPyrDown( out ); out = doCanny( out, 10, 100, 3 ); ... cvReleaseImage( &out); 以下是完整程序:

    #include "cv.h" #include "highgui.h" IplImage* doCanny( IplImage* in, double lowThresh, double highThresh, double aperture) { IplImage* out = cvCreateImage( cvGetSize( in ), in->depth, //IPL_DEPTH_8U, 1); cvCanny( in, out, lowThresh, highThresh, aperture ); return( out ); }; IplImage* doPyrDown( IplImage* in, int filter = IPL_GAUSSIAN_5x5) { // Best to make sure input image is divisible by two. // assert( in->width%2 == 0 && in->height%2 == 0 ); IplImage* out = cvCreateImage( cvSize( in->width/2, in->height/2 ), in->depth, in->nChannels ); cvPyrDown( in, out ); return( out ); }; int main( int argc, char** argv ) { cvNamedWindow("Example Gray", CV_WINDOW_AUTOSIZE ); cvNamedWindow("Example Pyr", CV_WINDOW_AUTOSIZE ); cvNamedWindow("Example Canny", CV_WINDOW_AUTOSIZE ); IplImage* img_rgb = cvLoadImage( argv[1] ); IplImage* out; out = cvCreateImage( cvSize( img_rgb->width,img_rgb->height ), img_rgb->depth, 1); cvCvtColor(img_rgb, out ,CV_BGR2GRAY); cvShowImage("Example Gray", out ); out = doPyrDown( out ); out = doPyrDown( out ); cvShowImage("Example Pyr", out ); out = doCanny( out, 10, 100, 3 ); cvShowImage("Example Canny", out ); cvWaitKey(0); cvReleaseImage( &out); cvDestroyWindow("Example Gray"); cvDestroyWindow("Example Pyr"); cvDestroyWindow("Example Canny"); }

    二、打开摄像头

    【问题】:用opencv3.0运行打开摄像头的程序时,只显示灰色。并且运行几次后要求选择摄像头,随后闪退。 【原因】: 以下是网络版,2.4.9,3.0运行成功:

    #include <opencv2\core\core.hpp> #include <opencv2\highgui\highgui.hpp> #include <opencv2\opencv.hpp> using namespace cv;//命名空间 int main() { VideoCapture capture(0);//创建VideoCapture对象 if (!capture.isOpened())//判断是否打开摄像头,打开isOpened返回ture return 1; bool stop(false);//定义一个用来停止循环的变量 Mat frame;//用来存放读取的视频序列,承载每一帧的图像 ,Mat类是用于保存图像以及其他矩阵数据的数据结构 namedWindow("Camera");//创建一个窗口,显示每一帧的窗口 while (!stop) { if (!capture.read(frame))//如果没有读取到就中断 { break; } imshow("Camera", frame);//正常显示,把获取的视频填充到窗口中 char c = cvWaitKey(33); if (c == 32)break; //使用空格键来停止ASCII 为32 } capture.release();//释放 }

    以下是书p30的版本,出现闪退情况,待解决:

    #include "cv.h" #include "highgui.h" int main(int argc, char** argv) { cvNamedWindow("Example2_9", CV_WINDOW_AUTOSIZE); CvCapture* capture; if (argc == 1) { capture = cvCreateCameraCapture(0); } else { capture = cvCreateFileCapture(argv[1]); } assert(capture != NULL); IplImage* frame; while (1) { frame = cvQueryFrame(capture); if (!frame) break; cvShowImage("Example2_9", frame); char c = cvWaitKey(10); if (c == 27) break; } cvReleaseCapture(&capture); cvDestroyWindow("Example2_9"); }

    网上的测试程序,3.0无法打开,2.4.9可以:

    #include <opencv2\opencv.hpp> #include<stdio.h> using namespace std; int main(int argc, char** argv) { //声明IplImage指针 IplImage* pFrame = NULL; //获取摄像头 CvCapture* pCapture = cvCaptureFromCAM(0);// cvCreateCameraCapture(0); cvWaitKey(200); //创建窗口 cvNamedWindow("Video", 1); //显示视屏 while (1) { pFrame = cvQueryFrame(pCapture); if (!pFrame)break; cvShowImage("Video", pFrame); char c = cvWaitKey(33); if (c == 27)break; } cvReleaseCapture(&pCapture); cvDestroyWindow("Video"); return 0; }

    【问题】:不能显示图像。 【原因】:命令参数里有别的变量忘记删了。


    网上的测试程序,显示灰色:

    //#include "stdafx.h" #include <cv.h> #include <cxcore.h> #include <highgui.h> int main(int argc, char** argv) { //声明IplImage 指针 IplImage* pFrame = NULL; //获取摄像头 CvCapture* pCapture = cvCreateCameraCapture(-1); //创建窗口 cvNamedWindow("video", 1); //显示视屏 while (1) { pFrame = cvQueryFrame(pCapture); if (!pFrame)break; cvShowImage("video", pFrame); char c = cvWaitKey(33); if (c == 27)break; } cvReleaseCapture(&pCapture); cvDestroyWindow("video"); }

    【问题】:#include "stdafx.h"没有这个文件。若注释掉则出现选择摄像机的界面且闪退。 【解决】:注释掉#include "stdafx.h"; CvCapture* pCapture = cvCreateCameraCapture(-1);不可用 【原因】:

    所谓头文件预编译,就是把一个工程(Project)中使用的一些MFC标准头文件(如Windows.H、Afxwin.H)预先编译,以后该工程编译时,不再编译这部分头文件,仅仅使用预编译的结果。这样可以加快编译速度,节省时间。 预编译头文件通过编译stdafx.cpp生成,以工程名命名,由于预编译的头文件的后缀是“pch”,所以编译结果文件是projectname.pch。 编译器通过一个头文件stdafx.h来使用预编译头文件。stdafx.h这个头文件名是可以在project的编译设置里指定的。编译器认为,所有在指令#include “stdafx.h”前的代码都是预编译的,它跳过#include “stdafx. h”指令,使用projectname.pch编译这条指令之后的所有代码。 因此,所有的MFC实现文件第一条语句都是:#include “stdafx.h”。


    小结:摄像头打不开,有版本问题,命令参数问题,(可能是stdafx.h问题)。

    ps:对于闪退问题,从网上查到的解决方法是:在return语句前面加上system(“pause”);,另外加上头文件include

    转载请注明原文地址: https://ju.6miu.com/read-678353.html

    最新回复(0)