【AI】基于OpenCV开发自定义程序编译方法

2023-05-16

基于OpenCV开发自定义程序编译方法

OpenCV自带的程序,编译均采用cmake统一编译。若我们要基于OpenCV开发自己的程序,如何快速编译?

本文以OpenCV库自带的facedetect.cpp程序作为模板,提供独立编译自定义程序的命令,和通用Makefile写法。

// 这是OpenCV库自带的sample程序,用于演示人脸/眼睛/鼻子侦测,我们将文件命名为facedetect.cpp
#include "opencv2/objdetect.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include <iostream>

using namespace std;
using namespace cv;

static void help()
{
    cout << "\nThis program demonstrates the cascade recognizer. Now you can use Haar or LBP features.\n"
            "This classifier can recognize many kinds of rigid objects, once the appropriate classifier is trained.\n"
            "It's most known use is for faces.\n"
            "Usage:\n"
            "./facedetect [--cascade=<cascade_path> this is the primary trained classifier such as frontal face]\n"
               "   [--nested-cascade[=nested_cascade_path this an optional secondary classifier such as eyes]]\n"
               "   [--scale=<image scale greater or equal to 1, try 1.3 for example>]\n"
               "   [--try-flip]\n"
               "   [filename|camera_index]\n\n"
            "see facedetect.cmd for one call:\n"
            "./facedetect --cascade=\"../../data/haarcascades/haarcascade_frontalface_alt.xml\" --nested-cascade=\"../../data/haarcascades/haarcascade_eye_tree_eyeglasses.xml\" --scale=1.3\n\n"
            "During execution:\n\tHit any key to quit.\n"
            "\tUsing OpenCV version " << CV_VERSION << "\n" << endl;
}

void detectAndDraw( Mat& img, CascadeClassifier& cascade,
                    CascadeClassifier& nestedCascade,
                    double scale, bool tryflip );

string cascadeName;
string nestedCascadeName;

int main( int argc, const char** argv )
{
    VideoCapture capture;
    Mat frame, image;
    string inputName;
    bool tryflip;
    CascadeClassifier cascade, nestedCascade;
    double scale;

    cv::CommandLineParser parser(argc, argv,
        "{help h||}"
        "{cascade|../../data/haarcascades/haarcascade_frontalface_alt.xml|}"
        "{nested-cascade|../../data/haarcascades/haarcascade_eye_tree_eyeglasses.xml|}"
        "{scale|1|}{try-flip||}{@filename||}"
    );
    if (parser.has("help"))
    {
        help();
        return 0;
    }
    cascadeName = parser.get<string>("cascade");
    nestedCascadeName = parser.get<string>("nested-cascade");
    scale = parser.get<double>("scale");
    if (scale < 1)
        scale = 1;
    tryflip = parser.has("try-flip");
    inputName = parser.get<string>("@filename");
    if (!parser.check())
    {
        parser.printErrors();
        return 0;
    }
    if ( !nestedCascade.load( nestedCascadeName ) )
        cerr << "WARNING: Could not load classifier cascade for nested objects" << endl;
    if( !cascade.load( cascadeName ) )
    {
        cerr << "ERROR: Could not load classifier cascade" << endl;
        help();
        return -1;
    }
    if( inputName.empty() || (isdigit(inputName[0]) && inputName.size() == 1) )
    {
        int camera = inputName.empty() ? 0 : inputName[0] - '0';
        if(!capture.open(camera))
            cout << "Capture from camera #" <<  camera << " didn't work" << endl;
    }
    else if( inputName.size() )
    {
        image = imread( inputName, 1 );
        if( image.empty() )
        {
            if(!capture.open( inputName ))
                cout << "Could not read " << inputName << endl;
        }
    }
    else
    {
        image = imread( "../data/lena.jpg", 1 );
        if(image.empty()) cout << "Couldn't read ../data/lena.jpg" << endl;
    }

    if( capture.isOpened() )
    {
        cout << "Video capturing has been started ..." << endl;

        for(;;)
        {
            capture >> frame;
            if( frame.empty() )
                break;

            Mat frame1 = frame.clone();
            detectAndDraw( frame1, cascade, nestedCascade, scale, tryflip );

            char c = (char)waitKey(10);
            if( c == 27 || c == 'q' || c == 'Q' )
                break;
        }
    }
    else
    {
        cout << "Detecting face(s) in " << inputName << endl;
        if( !image.empty() )
        {
            detectAndDraw( image, cascade, nestedCascade, scale, tryflip );
            waitKey(0);
        }
        else if( !inputName.empty() )
        {
            /* assume it is a text file containing the
            list of the image filenames to be processed - one per line */
            FILE* f = fopen( inputName.c_str(), "rt" );
            if( f )
            {
                char buf[1000+1];
                while( fgets( buf, 1000, f ) )
                {
                    int len = (int)strlen(buf);
                    while( len > 0 && isspace(buf[len-1]) )
                        len--;
                    buf[len] = '\0';
                    cout << "file " << buf << endl;
                    image = imread( buf, 1 );
                    if( !image.empty() )
                    {
                        detectAndDraw( image, cascade, nestedCascade, scale, tryflip );
                        char c = (char)waitKey(0);
                        if( c == 27 || c == 'q' || c == 'Q' )
                            break;
                    }
                    else
                    {
                        cerr << "Aw snap, couldn't read image " << buf << endl;
                    }
                }
                fclose(f);
            }
        }
    }

    return 0;
}

void detectAndDraw( Mat& img, CascadeClassifier& cascade,
                    CascadeClassifier& nestedCascade,
                    double scale, bool tryflip )
{
    double t = 0;
    vector<Rect> faces, faces2;
    const static Scalar colors[] =
    {
        Scalar(255,0,0),
        Scalar(255,128,0),
        Scalar(255,255,0),
        Scalar(0,255,0),
        Scalar(0,128,255),
        Scalar(0,255,255),
        Scalar(0,0,255),
        Scalar(255,0,255)
    };
    Mat gray, smallImg;

    cvtColor( img, gray, COLOR_BGR2GRAY );
    double fx = 1 / scale;
    resize( gray, smallImg, Size(), fx, fx, INTER_LINEAR );
    equalizeHist( smallImg, smallImg );

    t = (double)getTickCount();
    cascade.detectMultiScale( smallImg, faces,
        1.1, 2, 0
        //|CASCADE_FIND_BIGGEST_OBJECT
        //|CASCADE_DO_ROUGH_SEARCH
        |CASCADE_SCALE_IMAGE,
        Size(30, 30) );
    if( tryflip )
    {
        flip(smallImg, smallImg, 1);
        cascade.detectMultiScale( smallImg, faces2,
                                 1.1, 2, 0
                                 //|CASCADE_FIND_BIGGEST_OBJECT
                                 //|CASCADE_DO_ROUGH_SEARCH
                                 |CASCADE_SCALE_IMAGE,
                                 Size(30, 30) );
        for( vector<Rect>::const_iterator r = faces2.begin(); r != faces2.end(); ++r )
        {
            faces.push_back(Rect(smallImg.cols - r->x - r->width, r->y, r->width, r->height));
        }
    }
    t = (double)getTickCount() - t;
    printf( "detection time = %g ms\n", t*1000/getTickFrequency());
    for ( size_t i = 0; i < faces.size(); i++ )
    {
        Rect r = faces[i];
        Mat smallImgROI;
        vector<Rect> nestedObjects;
        Point center;
        Scalar color = colors[i%8];
        int radius;

        double aspect_ratio = (double)r.width/r.height;
        if( 0.75 < aspect_ratio && aspect_ratio < 1.3 )
        {
            center.x = cvRound((r.x + r.width*0.5)*scale);
            center.y = cvRound((r.y + r.height*0.5)*scale);
            radius = cvRound((r.width + r.height)*0.25*scale);
            circle( img, center, radius, color, 3, 8, 0 );
        }
        else
            rectangle( img, cvPoint(cvRound(r.x*scale), cvRound(r.y*scale)),
                       cvPoint(cvRound((r.x + r.width-1)*scale), cvRound((r.y + r.height-1)*scale)),
                       color, 3, 8, 0);
        if( nestedCascade.empty() )
            continue;
        smallImgROI = smallImg( r );
        nestedCascade.detectMultiScale( smallImgROI, nestedObjects,
            1.1, 2, 0
            //|CASCADE_FIND_BIGGEST_OBJECT
            //|CASCADE_DO_ROUGH_SEARCH
            //|CASCADE_DO_CANNY_PRUNING
            |CASCADE_SCALE_IMAGE,
            Size(30, 30) );
        for ( size_t j = 0; j < nestedObjects.size(); j++ )
        {
            Rect nr = nestedObjects[j];
            center.x = cvRound((r.x + nr.x + nr.width*0.5)*scale);
            center.y = cvRound((r.y + nr.y + nr.height*0.5)*scale);
            radius = cvRound((nr.width + nr.height)*0.25*scale);
            circle( img, center, radius, color, 3, 8, 0 );
        }
    }
    imshow( "result", img );
}

#命令行编译:
g++ facedetect.cpp -o facedetect `pkg-config --cflags --libs opencv`

#Makefile编译:
CFLAGS = `pkg-config --cflags opencv`
LIBS = `pkg-config --libs opencv`

APP_NAME = facedetect

OBJS = facedetect.o

$(APP_NAME) : $(OBJS)
        g++ $^ -o $(APP_NAME) $(LIBS)

%.o : %.cpp
        g++ $(CFLAGS) -c $^ -o $(OBJS)

clean:
        rm -rf *.o  $(APP_NAME)

#pkg-config解释,见man pkg-config说明:
NAME
       pkg-config - Return metainformation about installed libraries

SYNOPSIS
       pkg-config  [--modversion] [--help] [--print-errors] [--silence-errors] [--cflags] [--libs] [--libs-only-L] [--libs-only-l] [--cflags-only-I] [--variable=VARIABLENAME] [--define-variable=VARIABLENAME=VARIABLEVALUE] [--print-
       variables] [--uninstalled] [--exists] [--atleast-version=VERSION] [--exact-version=VERSION] [--max-version=VERSION] [--list-all] [LIBRARIES...]  [--print-provides] [--print-requires] [--print-requires-private] [LIBRARIES...]

DESCRIPTION
       The pkg-config program is used to retrieve information about installed libraries in the system.  It is typically used to compile and link against one or more libraries.  Here is a typical usage scenario in a Makefile:

       program: program.c
            cc program.c $(pkg-config --cflags --libs gnomeui)

       pkg-config retrieves information about packages from special metadata files. These files are named after the package, and has a .pc extension.  On most systems, pkg-config looks in  /usr/lib/pkgconfig,  /usr/share/pkgconfig,
       /usr/local/lib/pkgconfig  and  /usr/local/share/pkgconfig  for these files.  It will additionally look in the colon-separated (on Windows, semicolon-separated) list of directories specified by the PKG_CONFIG_PATH environment
       variable.

       The package name specified on the pkg-config command line is defined to be the name of the metadata file, minus the .pc extension. If a library can install multiple versions simultaneously, it must give each version its  own
       name (for example, GTK 1.2 might have the package name "gtk+" while GTK 2.0 has "gtk+-2.0").

       In addition to specifying a package name on the command line, the full path to a given .pc file may be given instead. This allows a user to directly query a particular .pc file.


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【AI】基于OpenCV开发自定义程序编译方法 的相关文章

  • 从高考到程序员--------你到底在追求着什么?------串烧似的文章

    随便写写 xff0c 万事开头难 xff0c 不知道应该怎么写出来 xff0c 因为只有自己经历的才能是最美好的回忆 xff0c 不知道这个编辑器写的效果如何 xff0c 凑合着看吧 xff0c 从高考到程序员征文看了几篇 xff0c 决定
  • AI以来----已不再是未来

    在过去的2016年 xff0c 可以说AI的核心发展一直围绕着开源和生态 国际巨头纷纷涉足深度学习平台 xff0c 让原本是高高在上的人工智能 xff0c 迅速落地细化到了行业的各个领域 随着AI技术正在为全球开发者所用 xff0c 极大的
  • 即兴嘻哈

    kao ha wowo 深夜不能寐 xff0c 那个翻来覆也不能把觉睡 一首即兴style说说ni为何半夜还不睡 xff0c 一线城市压力大来人总疲惫 xff0c 为了买房买车拼命都在向前奔 年轻人出来打拼为何这么累 xff0c 多少人为了
  • 裸辞3个月扛不住后,随便接了offer更惨!

    最近发现年底找工作的人不少 xff0c 部门里就2个hc xff0c 一周能收2000 43 简历 xff0c 这比例有点 过分 了 虽说大部分是年底先看看机会试试水 xff0c 准备年后冲击的 xff0c 但看简历里也有不少中间裸辞的 x
  • Docker常用命令-自用

    Docker常用命令 自用 1 镜像仓库 1 1 登陆 登出 登陆 默认Docker Hub docker login u span class token punctuation span username span class toke
  • 程序猿的浪漫之二进制表白篇

    那天情人节 xff0c 我给她发了一串数字 xff08 01001001 00100000 01101100 01101111 01110110 01100101 00100000 01111001 01101111 01110101 xf
  • Dockerfile使用教程

    第一 创建一个spring boot项目 第二 创建 xff1a Dockerfile文件 xff08 在项目根目录下 xff09 第三 复制粘贴 FROM java 8 设置基础镜像 FROM openjdk 8 jdk alpine 指
  • C++ 用socket封装成http

    HttpSocket h interface for the CHttpSocket class if defined AFX HTTPSOCKET H F49A8F82 A933 41A8 AF47 68FBCAC4ADA6 INCLUD
  • echarts更换主题

    前言 本篇文章基于上一篇文章 xff1a vue工程整合echarts xff0c 因此这里主要讲的是主题是如何配置的 xff0c 其他代码在这里不再赘述 官网中已经说明了echarts除了有默认的主题外 xff0c 并且内置了dark主题
  • Java final修饰符详解

    final 在 Java 中的意思是最终 xff0c 也可以称为完结器 xff0c 表示对象是最终形态的 xff0c 不可改变的意思 final 应用于类 方法和变量时意义是不同的 xff0c 但本质是一样的 xff0c 都表示不可改变 x
  • Python Requests库安装和使用

    Python 提供了多个用来编写爬虫程序的库 xff0c 除了前面已经介绍的 urllib 库之外 xff0c 还有一个很重的 Requests 库 xff0c 这个库的宗旨是 让 HTTP 服务于人类 Requests 是 Python
  • C语言 十进制转十六进制

    问题描述 十六进制数是在程序设计时经常要使用到的一种整数的表示方式 它有0 1 2 3 4 5 6 7 8 9 A B C D E F共16个符号 xff0c 分别表示十进制数的0至15 十六进制的计数方法是满16进1 xff0c 所以十进
  • Pandas知识点超全总结

    Pandas知识点超全总结 一 数据结构1 Series1 创建2 切片 修改3 其他属性 2 DataFrame1 创建2 切片3 增加 修改4 删除5 查看 二 读写数据1 读数据1 excel文件2 csv文件3 sql文件 2 写数
  • socket通信小结

    1 网络中的进程之间如何进行通信 区别于本地的进程间通信 xff0c 我们首要解决的问题是如何唯一标识一个进程 xff0c 否则通信无从谈起 xff01 在本地可以通过进程PID来唯一标识一个进程 xff0c 但是在网络中这是行不通的 其实
  • eclipse alt+/代码智能提示总是报错:problems during content assist

    解决办法如下图 xff1a 依次点击红框标记的地方即可解决问题
  • linux C 遍历目录及其子目录 opendir -> readdir -> closedir

    在 linux 下遍历某一目录下内容 LINUX 下历遍目录的方法一般是这样的 xff1a 打开目录 gt 读取 gt 关闭目录 相关函数是 opendir gt readdir gt closedir xff0c 其原型如下 xff1a
  • 最全面的 linux 信号量解析

    一 xff0e 什么是信号量 信号量的使用主要是用来保护共享资源 xff0c 使得资源在一个时刻只有一个进程 xff08 线程 xff09 所拥有 信号量的值为正的时候 xff0c 说明它空闲 所测试的线程可以锁定而使用它 若为 0 xff
  • vue3学习一:let和const

    在函数的内部 xff0c 定义name变量 xff0c 当i等于false时 xff0c 按照Java语言 xff0c else里是拿不到name的 xff0c 并且会显示报错 xff0c 但是却不会报错 xff0c 这是因为javascr
  • PHP 中最全的设计模式(23种)

    PhpDesignPatterns PHP 中的设计模式 一 Introduction 介绍 设计模式 xff1a 提供了一种广泛的可重用的方式来解决我们日常编程中常常遇见的问题 设计模式并不一定就是一个类库或者第三方框架 xff0c 它们
  • 异常详细信息: System.NullReferenceException: 未将对象引用设置到对象的实例。

    我遇到的出现这种错误的原因一般是以下几种情况 xff1a 1 在绑定数据控件的时候 xff0c 建立数据库连接 OleDbConnection conn 61 new OleDbConnection 34 provider 61 micro

随机推荐

  • 连接不上Github,网络超时的检查和解决办法

    先附上图片吧 连接不上github但是其它网站都是正常上网 解决办法 win 43 r打开运行输入cmd 再命令行里输入 ping github com 看看返回值 我的全是请求超时 xff0c 发送的数据包全丢 xff08 我先ping了
  • 2018校招笔试真题汇总

    2018校招笔试真题汇总 最近看好多牛油贡献了很多考试的真题 xff0c 我把他们汇总在一起给到大家 xff0c 也感谢这些牛油的贡献 xff0c 只要进这个汇总贴的 xff0c 你们都将每人获得一份牛客送出的礼物一份 科大讯飞 xff1a
  • 【2】Docker的启动与停止

    1 xff09 启动 docker systemctl start docker 2 xff09 查看 docker 状态 systemctl status docker 3 xff09 查看 docker 概要信息 docker info
  • 【8】Docker中部署Redis

    1 xff09 拉取镜像 docker pull redis 这是我在 VMware 的 CentOS 中装过的 redis 版本 xff0c 拉取该指定版本使用 docker pull redis 5 0 12 命令 xff0c 不过下面
  • 操作系统学习之系统调用

    目录 一 操作系统学习之系统调用 1 什么是系统调用 2 系统调用有什么用 3 为什么需要系统调用 4 系统调用的具体流程 1 xff09 执行过程 2 如何实现用户态与内态之间的切换 3 系统调用常见名词 4 系统调用如何返回 传递返回值
  • 22-Docker-常用命令详解-docker pull

    常用命令详解 docker pull 前言docker pull语法格式options说明 使用示例未指定tag a 拉取所有 tagged 镜像 前言 本篇来学习docker pull命令 docker pull 作用 xff1a 从镜像
  • 720p,1080p对应像素解释

    720P是1280 720 61 921600 xff0c 即 分辨率为921600 xff0c 即大约92万像素 xff0c 921600接近100万像素 xff08 1280是按照16 9算出来的 xff0c 4 3的另算 xff0c
  • vue3学习二:模板字符串

    模板字符串是为了解决字符串拼接问题 xff0c 在es5中 xff0c 字符串拼接是这样的 xff1a let name 61 34 wjdsg 34 console log 34 您好 34 43 name 而在es6中可以使用模板字符串
  • Canal 读取 mysql bin_log

    场景 xff1a 在微服务开发的过程中多个项目协同完成一个功能 xff0c 工程与工程之间存在数据上的解耦 xff0c 底层服务为上层服务提供数据 而底层服务有需要对数据进行管理 解决方案 xff1a 基本底层服务 通过 canal 获取
  • PuTTY连接Linux服务器被拒绝问题

    PuTTY连接Linux服务器被拒绝问题 1 使用命令 xff1a ssh localhost 查看是否安装ssh1 2需要手动安装ssh1 2 1 输入命令 xff1a 1 2 2 若是出现下图所示 xff1a 1 2 3 查看进程 xf
  • 实时数据同步工具<Maxwell 操作案例>

    文章目录 案例一 xff1a 监控MySQL中的数据并输出到控制台案例二 xff1a Maxwell监控mysql的数据输出到kafka案例三 xff1a 监控MySQL指定表的数据并输出到kafka 案例一 xff1a 监控MySQL中的
  • Docker 镜像 Tag 管理

    Author xff1a rab 良好的镜像版本命名习惯能让我们更好的管理和使用镜像 xff08 如项目上线失败后可有效的进行版本回退等 xff09 xff0c 以下是 Docker 社区常用的 tag 方案 比如我现在已经构建了一个 co
  • APM与Pixhawk间的关系

    1 APM 本文APM指代 xff1a https github com ArduPilot ardupilot 2 Pixhawk 本文Pixhawk指代 xff1a https github com PX4 Firmware 3 关系
  • Pixhawk串口名称与硬件接口对应关系

    Pixhawk提供的串口较多 xff0c 通过ls dev 可以看到有如下7个tty设备 xff1a ttyACM0 ttyS0 ttyS1 ttyS2 ttyS3 ttyS4 ttyS5 ttyS6 但每个串口名称对应到Pixhawk硬件
  • Linux系统大小端判断

    大端模式 大端模式 xff0c 是指数据的低位保存在内存的高地址中 xff0c 而数据的高位保存在内存的低地址中 小端模式 小端模式 xff0c 是指数据的低位保存在内存的低地址中 xff0c 而数据的高位保存在内存的高地址中 判断程序 文
  • C preprocessor fails sanity check

    编译某一产品固件时 xff0c 遇到如下现象 xff1a checking how to run the C preprocessor opt mipsel 24kec linux uclibc bin mipsel 24kec linux
  • VLC同时开启播放多个视频流BAT脚本

    工作中 xff0c 难免会遇到要用同一个程序连续打开多个URL资源 路径的情况 xff0c 一个窗口一个窗口的启动效率太低 这里以VLC同时播放多个码流图像为例 xff0c 写个简单的BAT脚本 xff0c 供需要者参考 PS 1 使用方式
  • 【AI】Ubuntu14.04安装OpenCV3.2.0

    在ubuntu14 04系统上安装OpenCV3 2 0 环境要求 GCC 4 4 x or later CMake 2 8 7 or higher Git if failed you can replace it with git cor
  • 若依代码生成器(mybatis-plus)

    看这篇文章之前 xff0c 先去看一下我前面的文章 xff1a 若依前后端分离整合mybatis plus wjdsg的博客 CSDN博客 用过若依都知道 xff0c 若依自带的代码生成器 xff0c 是下载下来 xff0c 然后自己粘贴到
  • 【AI】基于OpenCV开发自定义程序编译方法

    基于OpenCV开发自定义程序编译方法 OpenCV自带的程序 xff0c 编译均采用cmake统一编译 若我们要基于OpenCV开发自己的程序 xff0c 如何快速编译 xff1f 本文以OpenCV库自带的facedetect cpp程