Image 如何使用OpenCV查找图像上每个单独轮廓的高度和宽度

Image 如何使用OpenCV查找图像上每个单独轮廓的高度和宽度,image,opencv,image-processing,computer-vision,contour,Image,Opencv,Image Processing,Computer Vision,Contour,在上图中,如果指定了整个宽度,则表示为30'5“。如何使用opencv计算该图像上每个单独轮廓的高度和宽度; std::vector<std::vector<cv::Point2i>> vecContours; cv::Mat mat = cv::imread("[path to image]", cv::IMREAD_GRAYSCALE); cv::threshold(mat, mat, 200, 255, cv::THRESH_BINARY); cv::findCon

在上图中,如果指定了整个宽度,则表示为30'5“。如何使用opencv计算该图像上每个单独轮廓的高度和宽度;
std::vector<std::vector<cv::Point2i>> vecContours;
cv::Mat mat = cv::imread("[path to image]", cv::IMREAD_GRAYSCALE);
cv::threshold(mat, mat, 200, 255, cv::THRESH_BINARY);
cv::findContours(mat, vecContours, cv::RetrievalModes::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE);
float inchPerPixel = 30.5f / mat.cols;
for (const std::vector<cv::Point2i>& vecContour : vecContours) {
    cv::Rect2i contourRect = cv::boundingRect(vecContour);
    printf("Contour width pixels : %d, width inches %f\n", contourRect.width, inchPerPixel*contourRect.width);
}
cv::Mat Mat=cv::imread(“[图像路径]”,cv::imread\u灰度); cv::threshold(mat,mat,200255,cv::THRESH_二进制); cv::findContours(mat、vecContours、cv::RetrievalModes::RETR_EXTERNAL、cv::CHAIN_About_NONE); 每像素浮动英寸=30.5f/mat.cols; 用于(常量标准::向量和向量轮廓:向量轮廓){ cv::Rect2i-contourRect=cv::boundingRect(vecContour); printf(“轮廓宽度像素:%d,宽度英寸%f\n”,contourRect.width,inchPerPixel*contourRect.width); } 您可以通过以下方式实现此目的:

  • 使用阈值方法创建二值图像
  • 使用findContours方法查找图像中矩形的轮廓
  • 使用boundingRect方法获取矩形轮廓的大小
  • 将轮廓的长度乘以计算出的每像素英寸系数
  • 我的方法是:

    #包括“opencv2/highgui/highgui.hpp”
    #包括“opencv2/imgproc/imgproc.hpp”
    #包括
    #包括
    #包括
    使用名称空间cv;
    使用名称空间std;
    int main()
    {
    Mat src;Mat src_gray;
    int thresh=100;
    RNG RNG(12345);
    ///加载源图像并将其转换为灰色
    src=imread(“/ur/img/directory/image.jpg”,1);
    Mat original=src.clone();
    ///将图像转换为灰色并使其模糊
    CVT颜色(src、src_灰色、CV_BGR2灰色);
    Mat阈值输出;
    矢量等值线;
    向量层次;
    ///使用阈值检测边缘
    阈值(src_灰度,阈值_输出,阈值,255,阈值_二进制);
    ///寻找轮廓
    findContours(阈值输出、轮廓、层次、CV树、CV链近似、点(0,0));
    ///找到每个轮廓的旋转矩形
    向量minRect(contours.size());
    对于(int i=0;i长度_2)
    putText(原始,到字符串(temp1),矩形点[0],字体\u HERSHEY\u单纯形,1.0,标量(0255255),2);
    其他的
    putText(原始,到字符串(temp2),矩形点[0],字体\u HERSHEY\u单纯形,1.0,标量(0255255),2);
    直线(结果零点,矩形点[j],矩形点[(j+1)%4],颜色,1,8);
    }
    }
    ///在windows中显示
    imshow(“第一”,原件);
    imshow(“轮廓”,图纸);
    等待键(0);
    返回(0);
    }
    
    源图像:

    每行检测到的矩形:

    按像素划分的线条长度:


    要获得轮廓的高度和宽度,可以使用。该函数以
    x,y,w,h
    的形式返回轮廓信息。特定轮廓的高度将为
    h
    ,宽度将为
    w
    。以下是绘制到图像上的
    w
    像素的结果


    很棒的解决方案!但是从下一次使用Python如何,因为它更容易测试。大多数人可能没有C++环境设置!转换它到Python没什么大不了的。转换它没有困难。我的环境只是基于C++的。这就是为什么我在C++中回答的原因。
    #include "opencv2/highgui/highgui.hpp"
    #include "opencv2/imgproc/imgproc.hpp"
    #include <iostream>
    #include <stdio.h>
    #include <stdlib.h>
    
    using namespace cv;
    using namespace std;
    
    
    int main()
    {
    
        Mat src; Mat src_gray;
        int thresh = 100;
        RNG rng(12345);
        /// Load source image and convert it to gray
        src = imread( "/ur/img/directory/image.jpg", 1 );
        Mat original = src.clone();
        /// Convert image to gray and blur it
        cvtColor( src, src_gray, CV_BGR2GRAY );
    
        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) );
    
        /// Find the rotated rectangles for each contour
        vector<RotatedRect> minRect( contours.size() );
    
        for( int i = 0; i < contours.size(); i++ )
            minRect[i] = minAreaRect( Mat(contours[i]) );
    
        /// Draw contours + rotated rects
        Mat drawing = Mat::zeros( threshold_output.size(), CV_8UC3 );
        Mat result_zero = 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) );
            // detect contours
            drawContours( drawing, contours, i, color, 1, 8, vector<Vec4i>(), 0, Point() );
            // detect rectangle for each contour
            Point2f rect_points[4]; minRect[i].points( rect_points );
    
            double length_1 = cv::norm(cv::Mat(rect_points[0]),cv::Mat(rect_points[1]));
            double length_2 = cv::norm(cv::Mat(rect_points[1]),cv::Mat(rect_points[2]));
    
    
            for( int j = 0; j < 4; j++ )
            {
                int temp1 = (int)length_1;
                int temp2 = (int)length_2;
    
                if(length_1>length_2)
                    putText(original,to_string(temp1),rect_points[0],FONT_HERSHEY_SIMPLEX,1.0,Scalar(0,255,255),2);
                else
                    putText(original,to_string(temp2),rect_points[0],FONT_HERSHEY_SIMPLEX,1.0,Scalar(0,255,255),2);
    
                line( result_zero, rect_points[j], rect_points[(j+1)%4], color, 1, 8 );
            }
    
        }
    
        /// Show in windows
        imshow("First",original);
        imshow( "Contours", drawing );
        waitKey(0);
        return(0);
    }
    
    import cv2
    
    # Load image, convert to grayscale, Otsu's threshold
    image = cv2.imread('1.jpg')
    gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
    thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
    
    # Find contours, obtain bounding rect, and draw width
    cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    cnts = cnts[0] if len(cnts) == 2 else cnts[1]
    for c in cnts:
        x,y,w,h = cv2.boundingRect(c)
        cv2.putText(image, str(w), (x,y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (36,255,12), 2)
        cv2.rectangle(image, (x, y), (x + w, y + h), (36,255,12), 1)
    
    cv2.imshow('image', image)
    cv2.waitKey()