关于MinGW与MSVC编译器调用opencv出现的问题记录

这是我参与11月更文挑战的第19天,活动详情查看:2021最后一次更文挑战

一、OpenCV介绍

OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉库,本身源码代码主要由C和C++编写,支持跨平台编译运行。 比如: Linux、Windows、Android和Mac OS操作系统上都可以运行。因为源码主要是C和C++编写,运行效率非常高效; 并且OpenCV还同时提供了Python、Ruby、MATLAB等语言的接口,跨语言调用OpenCV也非常方便。OpenCV里包含了很多图像处理和计算机视觉方面的通用算法。

二、问题场景与原因说明

在上篇文章里介绍了Qt里如何调用OpenCV,在windows下使用MSVC编译器调用OpenCV时,使用了OpenCV里的某些函数会导致程序异常终止,例如: 调用级联分类器 face_cascade.detectMultiScale 函数进行目标分类检测时,采用MSVC编译器调用会导致程序异常崩溃,使用opencv调用YOLO模型进行目标检测,也会导致软件崩溃;库是使用OpenCV官方下载的库(版本3.4.7),使用的是64位库,可能是因为库编译器的版本和当前MSVC编译器版本不匹配导致,网上很多帖子提供的解决办法是重新用当前使用的MSVC编译器重新编译库,这个我没有测试过;但是使用MinGW编译器运行同样的代码一切正常,使用的OpenCV版本库是使用当前使用的同款编译器编译器,但不是我自己编译,从这里下载的,link.juejin.cn/?target=htt…

这也证明,崩溃的原因不是代码问题,是OpenCV库和当前编译器不匹配导致的,解决办法那就只有自己重新编译源码,或者去找对应编译器的OpenCV库。

image.png

下面几张图是OpenCV调用YOLO V3模型完成的识别:

image.png

image.png

image.png

Mat frame,frame_src,blob;
int inpWidth, inpHeight;

string names_file = "yolov3/yolo.names";
string model_def = "yolov3/yolov3.cfg";
string weights = "yolov3/yolov3.weights";

double thresh = 0.5;
double nms_thresh = 0.4; //0.4  0.25
inpWidth = inpHeight = 320; //416 608

//read names
ifstream ifs(names_file.c_str());
string line;
while (getline(ifs, line))classes.push_back(line);

//初始化模型
Net net = readNetFromDarknet(model_def, weights);
net.setPreferableBackend(DNN_BACKEND_OPENCV);
net.setPreferableTarget(DNN_TARGET_CPU);
复制代码

三、OpenCV几个简单案例用法

3.1 采用opencv 读取视频帧

VideoCapture capture;
capture.open("D:/linux-share-dir/video-01.avi");
if (!capture.isOpened())
{
  qDebug()<<"can't open video";
  return;
}
Mat frame;
while(capture.read(frame))
{
  /*在控件上显示识别结果*/
  //ui->label_2->setPixmap(QPixmap::fromImage(Mat2QImage(frame)));
  imshow("img",frame);
  qDebug()<<"1";
}
复制代码

3.2 将图片转为灰度图像

#include <cv.h>  
#include <cxcore.h>  
#include <highgui.h>  
          
int main(int argc,char **argv)  
{  
    CvCapture* capture = NULL;  
    IplImage* pImg = NULL; 
    IplImage* pImg1 = NULL; 
    pImg = cvLoadImage(argv[1],1);
    pImg1 = cvCreateImage(cvSize(pImg->width,pImg->height),IPL_DEPTH_8U,1);
    cvCvtColor(pImg,pImg1,CV_RGB2GRAY);
    cvSaveImage("a.bmp",pImg1);
    cvSaveImage("a.jpg",pImg1);
    cvSaveImage("a.png",pImg1);
    cvReleaseImage( &pImg );   
    cvReleaseImage( &pImg1 );   
    return 0;  
}
复制代码

3.3 python调用opencv打开一张图片显示

import cv2
#加载图片
src=cv2.imread("D:/linux-share-dir/888.jpg")
#第一个参数是窗口名字,第二个表示窗口大小可以调整
cv2.namedWindow("input image",cv2.WINDOW_NORMAL);
#显示图片
cv2.imshow("input image",src);
cv2.waitKey(0);
复制代码

3.3 python调用opencv打开摄像头实时显示

import numpy as np
import cv2
#调用笔记本内置摄像头,所以参数为0,如果有其他的摄像头可以调整参数为1,2
cap=cv2.VideoCapture(0)
while True:
    #从摄像头读取图片
    sucess,img=cap.read()
    #转为灰度图片
    #gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    #显示摄像头,背景是灰度。
    #cv2.imshow("img",gray)
    cv2.imshow("img",img) #显示彩图
    #保持画面的持续。
    k=cv2.waitKey(1)
    if k == 27:
        #通过esc键退出摄像
        cv2.destroyAllWindows()
        break
    elif k==ord("s"):
        #通过s键保存图片,并退出。
        cv2.imwrite("image2.jpg",img)
        cv2.destroyAllWindows()
        break
#关闭摄像头
cap.release()
复制代码

おすすめ

転載: juejin.im/post/7032076608089522183