首页 > 其他分享 >C代码实践——《Head first C》C语言实验室2

C代码实践——《Head first C》C语言实验室2

时间:2024-02-15 11:25:06浏览次数:32  
标签:Head frame flow prevGray C语言 opencv nextGray NULL first

目录

任务要求

入侵者检测器
计算机用摄像头持续监测周围环境,当检测到有物体在移动时就会把当前捕捉到的图像保存为文件。

完成过程

Step1.安装OpenCV

访问OpenCV官网下载适合操作系统的OpenCV,我起初下载的是最新版,但后来了解到最新版删除了不少旧版的C语言接口,就下回了2.x旧版本。

Step2.配置环境变量

将OpenCV的bin目录添加到系统环境变量中,具体操作如下

Step3.配置编译环境

创建工程并准备初步测试代码,在工程文件相应位置(我用vscode就在.vscode文件夹里)大致配置好tasks.json、c_cpp_properties.json,并进行测试
这是我第一次配置,我捯饬了老半天,一边问GPT一边自己瞎试,其实关键就是成功链接到opencv的相应库。

我的tasks.json配置如下:

{
    "tasks": [
        {
            "type": "cppbuild",
            "label": "C/C++: gcc.exe 生成活动文件",
            "command": "C:/Program Files/mingw64/bin/gcc.exe",
            "args": [
                "-fdiagnostics-color=always",
                "-g",
                "${file}",
                "-o",
                "${fileDirname}\\${fileBasenameNoExtension}.exe",
                "-ID:/opencv/opencv/build/include",
                "-LD:/opencv/opencv/build/x64/vc14/lib",
                "-lopencv_core2413",
                "-lopencv_imgproc2413",
                "-lopencv_highgui2413",
                "-lopencv_video2413"
            ],
            "options": {
                "cwd": "C:/Program Files/mingw64/bin"
            },
            "problemMatcher": [
                "$gcc"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "detail": "调试器生成的任务。"
        }
    ],
    "version": "2.0.0"
}

我的c_cpp_properties.json配置如下:

{
    "configurations": [
        {
            "name": "Win32",
            "includePath": [
                "${workspaceFolder}/**",
                "D:/opencv/opencv/build/include/"
            ],
            "defines": [],
            "windowsSdkVersion": "10.0.17763.0",
            "compilerPath": "C:/Program Files/mingw64/bin/gcc.exe",
            "cStandard": "c11",
            "cppStandard": "c++17",
            "intelliSenseMode": "${default}"
        }
    ],
    "version": 4
}

Step4.编写程序代码

按照任务要求与提示编写程序代码.现在有了GPT,方便很多,不懂的函数,直接让GPT手把手带你写,但这里我也出了不少几次错误,不过问GPT加自己“研究”(瞎捣鼓)也凑活写出来了。(具体代码见文尾)

Step5.测试运行调整

试运行程序并对程序代码进行调整。刚开始运行的时候,我人晃半天都检测不到,然后我就修改参数,改了几次之后也就差不多了。

反思、总结、收获

程序也凑合着能用了,但真要达到目的恐怕远远不够(比如这个程序只能记录最后一个可疑图像,而这个图像往往是thief离开的图像,很难看清thief)。
这个过程也是一波三折,一开始不知道配置环境变量,然后不会配置tasks.json、c_cpp_properties.json,后来程序也老是出错,折腾几天,有点头疼。不过这个过程也的的确确锻炼了自己做工程写程序的能力,积攒了相关的经验

最终程序代码

#include <opencv2/highgui/highgui_c.h>
#include <opencv2/imgproc/imgproc_c.h>
#include <opencv/cv.h>
#include <stdio.h>

int main()
{
    CvCapture *capture = cvCaptureFromCAM(0); // 从默认摄像头捕获视频
    if (!capture)
    {
        fprintf(stderr, "错误:无法打开摄像头\n");
        return -1;
    }

    IplImage *frame;
    IplImage *prev;
    IplImage *next;
    IplImage *prevGray;
    IplImage *nextGray;
    fprintf(stderr, "successly start!\n");

    while (1)
    {
        frame = cvQueryFrame(capture); // 从摄像头捕获一帧图像
        if (!frame)
            break;

        // 加载两帧图像
        prev = cvQueryFrame(capture);
        next = cvQueryFrame(capture);

        // 为灰度图像分配空间
        prevGray = cvCreateImage(cvGetSize(frame), IPL_DEPTH_8U, 1);
        nextGray = cvCreateImage(cvGetSize(frame), IPL_DEPTH_8U, 1);

        // 将第一帧转换为灰度
        cvCvtColor(frame, prevGray, CV_BGR2GRAY);
        cvCvtColor(frame, nextGray, CV_BGR2GRAY);

        // 创建光流图像
        CvSize img_sz = cvGetSize(prevGray);
        CvMat *flow = cvCreateMat(img_sz.height, img_sz.width, CV_32FC2);

        // 计算光流
        cvCalcOpticalFlowFarneback(prevGray, nextGray, flow, 0.5, 5, 31, 3, 7, 1.5, 0);

        for (int y = 0; y < flow->rows; y++)
        {
            float *flow_ptr = (float *)(flow->data.ptr + flow->step * y);
            for (int x = 0; x < flow->cols; x++)
            {
                float x_flow = flow_ptr[x * 2];
                float y_flow = flow_ptr[x * 2 + 1];

                // 计算向量的大小(magnitude)
                float magnitude = sqrt(x_flow * x_flow + y_flow * y_flow);

                if (2 * x + 1 >= flow->cols)
                    break;

                // 检测显著运动
                if (magnitude > 0.5)
                {
                    cvSaveImage("thief.jpg", next, 0);
                    // 在这里处理显著运动的逻辑
                }
            }
        }

        // 释放图像和光流数据
        if (prevGray != NULL)
        {
            cvReleaseImage(&prevGray);
            prevGray = NULL; // 将指针设为NULL,防止野指针
        }

        if (nextGray != NULL)
        {
            cvReleaseImage(&nextGray);
            nextGray = NULL; // 同上
        }

        if (prev != NULL)
        {
            cvReleaseImage(&prevGray);
            prevGray = NULL; // 将指针设为NULL,防止野指针
        }

        if (next != NULL)
        {
            cvReleaseImage(&nextGray);
            nextGray = NULL; // 同上
        }

        if (flow != NULL)
        {
            cvReleaseMat(&flow);
            flow = NULL; // 同上
        }
    }

    cvReleaseCapture(&capture); // 释放IplImage资源

    return 0;
}

标签:Head,frame,flow,prevGray,C语言,opencv,nextGray,NULL,first
From: https://www.cnblogs.com/zzz12138/p/18016072

相关文章

  • 掌握C语言文件操作:从入门到精通的完整指南!
    ✨✨欢迎大家来到贝蒂大讲堂✨✨......
  • bits/libc-header-start.h: No such file or directory
    问题出现在编译一个工程的时候,出现了报错Infileincludedfrom/usr/lib/gcc/x86_64-linux-gnu/9/include/stdint.h:9,frommain.c:1:/usr/includ......
  • openJudge | 统计学生信息(使用动态链表完成)C语言
    总时间限制:1000ms内存限制:65536kB描述利用动态链表记录从标准输入输入的学生信息(学号、姓名、性别、年龄、得分、地址)其中,学号长度不超过20,姓名长度不超过40,性别长度为1,地址长度不超过40输入包括若干行,每一行都是一个学生的信息,如:00630018zhouyanm2010.028......
  • 【c语言】字符串常见函数 下
    ......
  • c语言操作sqlite
    前言c语言只需要下载sqlite.dll即可操作数据库,qtsql只是对sqlite的api做了一层驱动包装而已下载    #include<stdio.h>#include<assert.h>#include<string.h>#include"sqlite3.h"voidsqlite3_test_get_table(sqlite3*db){char**rows=NULL;intnrow......
  • [LeetCode] 2108. Find First Palindromic String in the Array
    Givenanarrayofstringswords,returnthefirstpalindromicstringinthearray.Ifthereisnosuchstring,returnanemptystring"".Astringispalindromicifitreadsthesameforwardandbackward.Example1:Input:words=["abc&quo......
  • 【c语言】字符串常见函数 上
    ......
  • 【数据结构】C语言实现栈的相关操作
    栈栈是一种遵循先入后出逻辑的线性数据结构,是只能在表的一端进行插入和删除运算的线性表进行插入和删除的一端的称为栈顶,另一端称为栈底栈的操作规则是后进先出或者是先进后出栈可以用数组或者链表实现,用数组实现的叫做顺序栈,用链表实现的叫做链栈顺序栈表示(数组)在数组上......
  • [RxJS] firstValueFrom/lastValueFrom (convert observable to promise)
    Convertsanobservabletoapromisebysubscribingtotheobservable,andreturningapromisethatwillresolveassoonasthefirstvaluearrivesfromtheobservable.Thesubscriptionwillthenbeclosed.WARNING:Onlyusethiswithobservablesyou know ......
  • 一句话总结Kubernetes的Headless服务
    Kubernetes的概念很多,有的着实让人费解,比如说Headless服务,听名字就很拗口。那Headless服务是什么,使用场景是什么。一句话总结:Headless服务就是一组Pod组成的只供集群内访问(没有ClusterIP)的Service,一般结合StatefulSet用于部署有状态应用的场景。1、Service与服务发现提到Headl......