You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在OpenCV C++中用raspicam::RaspiCam_Cv替代cvCaptureFromAVI实现实时形状检测

Hey there! Let's get your real-time shape detection working with the Raspberry Pi camera. I've adapted your code to use raspicam::RaspiCam_Cv instead of reading from a video file, and added support for calling a custom function when a triangle is detected. Here's the breakdown and the updated code:

Key Changes Made

  • Replaced the old CvCapture video file reader with raspicam::RaspiCam_Cv for camera input
  • Updated camera initialization and frame capture logic to match raspicam's API
  • Added a sample custom function onTriangleDetected() that triggers when a valid triangle is found
  • Migrated some deprecated OpenCV C API calls to the more modern C++ interface while preserving your original shape detection logic

Updated Code

#include <opencv2/opencv.hpp>
#include <raspicam/raspicam_cv.h>
#include <iostream>
using namespace std;
using namespace cv;

Mat imgTracking;
int lastX1 = -1;
int lastY1 = -1;
int lastX2 = -1;
int lastY2 = -1;

// Your custom function to call when a triangle is detected
// Replace this with your actual desired functionality
void onTriangleDetected(int centerX, int centerY) {
    cout << "Triangle detected at center (" << centerX << ", " << centerY << ")!" << endl;
    // Add your specific function logic here, e.g., trigger a GPIO, send a signal, etc.
}

void trackObject(Mat& imgThresh) {
    vector<vector<Point>> contours;
    vector<Vec4i> hierarchy;

    // Find all contours in the thresholded image
    findContours(imgThresh, contours, hierarchy, RETR_LIST, CHAIN_APPROX_SIMPLE);

    // Iterate through each detected contour
    for (size_t i = 0; i < contours.size(); i++) {
        // Approximate the contour to a simplified polygon
        vector<Point> approx;
        approxPolyDP(contours[i], approx, arcLength(contours[i], true) * 0.02, true);

        // Check if the contour is a triangle with sufficient area
        if (approx.size() == 3 && fabs(contourArea(approx)) > 100) {
            // Calculate the center point of the triangle
            int posX = (approx[0].x + approx[1].x + approx[2].x) / 3;
            int posY = (approx[0].y + approx[1].y + approx[2].y) / 3;

            // Call your custom function when a triangle is found
            onTriangleDetected(posX, posY);

            // Preserve your original tracking line drawing logic
            if (posX > 360) {
                if (lastX1 >= 0 && lastY1 >= 0) {
                    line(imgTracking, Point(posX, posY), Point(lastX1, lastY1), Scalar(0, 0, 255), 4);
                }
                lastX1 = posX;
                lastY1 = posY;
            } else {
                if (lastX2 >= 0 && lastY2 >= 0) {
                    line(imgTracking, Point(posX, posY), Point(lastX2, lastY2), Scalar(255, 0, 0), 4);
                }
                lastX2 = posX;
                lastY2 = posY;
            }
        }
    }
}

int main() {
    raspicam::RaspiCam_Cv capture;

    // Configure camera settings (adjust as needed)
    capture.set(CAP_PROP_FRAME_WIDTH, 640);
    capture.set(CAP_PROP_FRAME_HEIGHT, 480);
    capture.set(CAP_PROP_BRIGHTNESS, 50);
    capture.set(CAP_PROP_CONTRAST, 50);
    capture.set(CAP_PROP_SATURATION, 50);

    // Initialize the camera
    if (!capture.open()) {
        cerr << "Failed to open Raspberry Pi camera!" << endl;
        return -1;
    }

    // Initialize the tracking overlay image
    imgTracking = Mat::zeros(capture.get(CAP_PROP_FRAME_HEIGHT), capture.get(CAP_PROP_FRAME_WIDTH), CV_8UC3);
    namedWindow("Video", WINDOW_AUTOSIZE);

    // Main loop for real-time detection
    while (true) {
        Mat frame;
        capture.grab();
        capture.retrieve(frame);

        if (frame.empty()) break;

        // Smooth the frame to reduce noise
        GaussianBlur(frame, frame, Size(3, 3), 0);

        // Convert to grayscale and apply threshold
        Mat imgGrayScale;
        cvtColor(frame, imgGrayScale, COLOR_BGR2GRAY);
        threshold(imgGrayScale, imgGrayScale, 100, 255, THRESH_BINARY_INV);

        // Run shape detection and tracking
        trackObject(imgGrayScale);

        // Combine tracking overlay with the original frame
        add(frame, imgTracking, frame);
        imshow("Video", frame);

        // Exit loop when ESC key is pressed
        char c = waitKey(10);
        if (c == 27) break;
    }

    // Cleanup resources
    destroyAllWindows();
    capture.release();
    return 0;
}

Compilation Command

When building the code, you'll need to link against both OpenCV and raspicam libraries. Use this command in your terminal:

g++ -o triangle_detector triangle_detector.cpp `pkg-config --cflags --libs opencv4 raspicam`

(Replace opencv4 with opencv if you're using an older version of OpenCV)

Quick Troubleshooting

  • If the camera fails to open, make sure you've enabled it in raspi-config (Interface Options > Camera)
  • Adjust the threshold value (100) if detection isn't working well under your lighting conditions
  • Tweak the arcLength multiplier (0.02) to control how closely the polygon approximation matches the original contour

内容的提问来源于stack exchange,提问作者Abdusoli

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 05:22:32