OpenCV技术求助:提取最大Bounding Box并裁剪原始图像
Hey, let's get this sorted for you! Your existing OpenCV code does a solid job detecting contours and drawing bounding boxes, but we need to add logic to pick out the largest rectangle (which should correspond to the car) and crop that area from your original image. Here's the modified code with clear explanations of what changed:
Modified Code
#include "opencv2/imgcodecs.hpp" #include "opencv2/imgproc.hpp" #include "opencv2/videoio.hpp" #include <opencv2/highgui.hpp> #include <opencv2/video.hpp> #include <iostream> #include <sstream> #include <fstream> using namespace cv; using namespace std; Mat src; Mat src_gray; int thresh = 0; int max_thresh = 255; RNG rng(12345); /// Function header void thresh_callback(int, void*); /** @function thresh_callback */ void thresh_callback(int, void*) { Mat threshold_output; vector<vector<Point> > contours; vector<Vec4i> hierarchy; /// Detect edges using Threshold threshold(src_gray, threshold_output, thresh, 255, THRESH_BINARY); /// Find contours findContours(threshold_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0)); /// Approximate contours to polygons + get bounding rects and circles vector<vector<Point> > contours_poly(contours.size()); vector<Rect> boundRect(contours.size()); vector<Point2f>center(contours.size()); vector<float>radius(contours.size()); for (int i = 0; i < contours.size(); i++) { approxPolyDP(Mat(contours[i]), contours_poly[i], 3, true); boundRect[i] = boundingRect(Mat(contours_poly[i])); minEnclosingCircle((Mat)contours_poly[i], center[i], radius[i]); } /// ------------------- New Logic: Find Largest Bounding Box ------------------- Rect largestRect; double maxArea = 0.0; // Loop through all rectangles to find the one with the biggest area for (size_t i = 0; i < boundRect.size(); ++i) { double currentArea = boundRect[i].area(); if (currentArea > maxArea) { maxArea = currentArea; largestRect = boundRect[i]; } } // Crop the original image using the largest rectangle if we found one if (maxArea > 0) { Mat croppedCar = src(largestRect); // Show the cropped result in a new window namedWindow("Cropped Car", CV_WINDOW_AUTOSIZE); imshow("Cropped Car", croppedCar); // Save the cropped image to your working directory imwrite("cropped_car.jpg", croppedCar); } /// --------------------------------------------------------------------------- /// Draw polygonal contour + bounding rects + circles Mat drawing = Mat::zeros(threshold_output.size(), CV_8UC3); for (int i = 0; i< contours.size(); i++) { Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)); drawContours(drawing, contours_poly, i, color, 1, 8, vector<Vec4i>(), 0, Point()); rectangle(drawing, boundRect[i].tl(), boundRect[i].br(), color, 2, 8, 0); // Highlight the largest rectangle with a thick red border for clarity if (boundRect[i] == largestRect) { rectangle(drawing, largestRect.tl(), largestRect.br(), Scalar(0, 0, 255), 4, 8, 0); } } /// Show contours window namedWindow("Contours", CV_WINDOW_AUTOSIZE); imshow("Contours", drawing); } /** @function main */ int main(int argc, char** argv) { /// Load source image and convert it to gray src = imread("RGB2YCrCb_BC_SB.png"); // Check if image loaded successfully (prevents crashes if file is missing) if (src.empty()) { cout << "Error: Could not open or find the input image!" << endl; return -1; } /// Convert image to gray and blur it cvtColor(src, src_gray, CV_BGR2GRAY); blur(src_gray, src_gray, Size(3, 3)); /// Create source image window char* source_window = "Source"; namedWindow(source_window, CV_WINDOW_AUTOSIZE); imshow(source_window, src); thresh_callback(0, 0); waitKey(0); return(0); }
Key Changes Explained
- Largest Rectangle Detection: We iterate through every detected bounding box, calculate its area using
boundRect[i].area(), and keep track of the rectangle with the maximum area. Since the car is the largest object in your input image, this should reliably target it. - Image Cropping: Using OpenCV's intuitive Mat slicing syntax
src(largestRect), we directly extract the region of interest (ROI) from the original color image—no need for manual coordinate calculations. - Visual Highlighting: To make it obvious which box we selected, we draw a thick red border around the largest rectangle in the "Contours" window.
- Error Handling: Added a check to ensure the input image loads successfully, so you get a clear error message instead of a crash if the file path is incorrect.
- Result Saving: The
imwritefunction saves the cropped car image to your working directory ascropped_car.jpgfor easy access.
内容的提问来源于stack exchange,提问作者kasra




