Opencv 和 c++ 框出图片中的目标

主要是使用opencv中的鼠标操作
—-setMOuseCallback函数的作用是为指定窗口设置鼠标回调函数,原型如下。

C++:void setMouseCallback(conststring& winname, MouseCallback onMouse,void* userdata = 0)
/*************************************************************************
    > File Name: 3-3.cpp
    > Author: zsj
    > Mail: fj_zsj@163.com 
    > Created Time: Wed 08 Mar 2017 07:11:58 PM CST
 ************************************************************************/

#include<iostream>
#include <cstdio>
#include <cstdlib>
#include <opencv2/opencv.hpp>

#define WINDOW_NAME "program_window"

using namespace cv;
using namespace std;

void on_MouseHandle(int event, int x, int y, int flags, void* param); //对鼠标触发事件进行判断处理
void DrawRectangle(cv::Mat& img, cv::Rect box); //画出矩形

int cnt;
Rect g_rectangle;           
bool g_bDrawingBox = false;//是否进行绘制
RNG g_rng(12345);          //Scalar格式

int main(int argc, char **argv)
{
        [1]初始化参数
    cnt = 0;
    g_rectangle = Rect(-1, -1, 0, 0);  

    Mat srcImage = imread("1.jpg");
    Mat tempImage;

    if ( !srcImage.data ) printf("read image fail!\n");

    srcImage.copyTo(tempImage);

//  g_rectangle = Rect(-1, -1, 0, 0);
//  srcImage = Scalar::all(0);       
        [2]设置鼠标操作回调函数
    namedWindow(WINDOW_NAME);
    setMouseCallback(WINDOW_NAME, on_MouseHandle, (void*)&srcImage);

        [3]开始判断是否进行绘制操作
    while(1) {
        srcImage.copyTo(tempImage); //复制源图到临时变量
        if( g_bDrawingBox ) DrawRectangle( tempImage, g_rectangle);

        imshow(WINDOW_NAME, tempImage);
        if (waitKey(10) == 27) break; //按下ESC键,程序退出
    }

    return 0;
}

//  鼠标回调函数,根据不同的鼠标事件进行不同的操作 
void on_MouseHandle(int event, int x, int y, int flags, void* param) {
    Mat& image = *(cv::Mat*) param;
    printf("----------<x,y>-----------\n");
    printf("cnt = %d, <%d %d>\n", ++cnt, x, y);
        printf("----------<x,y>-----------\n");
    switch( event ) {
            // 鼠标移动消息     
        case EVENT_MOUSEMOVE:{
                                 if (g_bDrawingBox) { 
                                  //绘制标识为真,则记录下长和宽到RECT变量中
                                     g_rectangle.width = x - g_rectangle.x;
                                     g_rectangle.height = y - g_rectangle.y;
                                 }
                             }
                             break;
        //左键按下消息
       case EVENT_LBUTTONDOWN:{ 
                                   g_bDrawingBox = true;
                                  g_rectangle = Rect(x, y, 0, 0);
                              }
                              break;
        //左键抬起消息
      case EVENT_LBUTTONUP: {
                                g_bDrawingBox = false;
                                if (g_rectangle.width < 0) {
                                    g_rectangle.x += g_rectangle.width;
                                    g_rectangle.width *= -1;
                                }

                                if (g_rectangle.height < 0) {
                                    g_rectangle.y += g_rectangle.height;
                                    g_rectangle.height *= -1;
                                }

                                DrawRectangle(image, g_rectangle );
                            }
                            break;
     default: printf("error!\n");
    }
}

//自定义的矩形绘制函数
void DrawRectangle(cv::Mat& img, cv::Rect box){
    rectangle(img, box.tl(), box.br(), Scalar(RNG(210), RNG(0),RNG(90)), 2, 1, 0);
}

Reference:
《OpenCV3编程入门》
《数字图像处理》
《c++编程》

  • 3
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
C++ 使用 OpenCV 和 YOLO 进行目标检测,可以按照以下步骤进行: 1. 下载 YOLO 的权重文件和配置文件,并将它们放在适当的位置。 2. 使用 OpenCV 加载图像或视频,并将其传递给 YOLO 进行目标检测。 3. 遍历 YOLO 的输出,并将检测到的边界框和类别绘制到图像或视频上。 以下是一个简单的 C++ 示例代码,演示了如何使用 OpenCV 和 YOLO 进行目标检测: ```c++ #include <opencv2/opencv.hpp> #include <iostream> using namespace cv; using namespace std; int main() { // 加载 YOLO 的权重文件和配置文件 String modelConfiguration = "yolov3.cfg"; String modelWeights = "yolov3.weights"; Net net = readNetFromDarknet(modelConfiguration, modelWeights); net.setPreferableBackend(DNN_BACKEND_OPENCV); net.setPreferableTarget(DNN_TARGET_CPU); // 加载图像或视频 Mat image = imread("test.jpg"); // 将图像传递给 YOLO 进行目标检测 Mat blob = blobFromImage(image, 1 / 255.0, Size(416, 416), Scalar(0, 0, 0), true, false); net.setInput(blob); vector<Mat> outs; net.forward(outs, getOutputsNames(net)); // 遍历 YOLO 的输出,并将检测到的边界框和类别绘制到图像上 float confThreshold = 0.5; vector<int> classIds; vector<float> confidences; vector<Rect> boxes; for (size_t i = 0; i < outs.size(); ++i) { // 获取当前输出层的信息 float* data = (float*)outs[i].data; for (int j = 0; j < outs[i].rows; ++j, data += outs[i].cols) { Mat scores = outs[i].row(j).colRange(5, outs[i].cols); Point classIdPoint; double confidence; minMaxLoc(scores, 0, &confidence, 0, &classIdPoint); if (confidence > confThreshold) { int centerX = (int)(data[0] * image.cols); int centerY = (int)(data[1] * image.rows); int width = (int)(data[2] * image.cols); int height = (int)(data[3] * image.rows); int left = centerX - width / 2; int top = centerY - height / 2; classIds.push_back(classIdPoint.x); confidences.push_back((float)confidence); boxes.push_back(Rect(left, top, width, height)); } } } // 非极大值抑制,去除重复的边界框 vector<int> indices; NMSBoxes(boxes, confidences, confThreshold, 0.4, indices); // 绘制检测到的边界框和类别 for (size_t i = 0; i < indices.size(); ++i) { int idx = indices[i]; Rect box = boxes[idx]; int classId = classIds[idx]; String className = "object"; rectangle(image, box, Scalar(0, 255, 0), 2); putText(image, className, Point(box.x, box.y - 10), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 255, 0), 2); } // 显示结果 imshow("YOLO object detection", image); waitKey(0); return 0; } ``` 注意,此处示例代码的模型文件和测试图片需要根据实际情况进行修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值