当前位置: 首页 > news >正文

OPENCV图形计算面积、弧长API讲解(2)

一.thresholdAPI讲解

作用:把图像进行二值化处理

在一个彩色图像中有许多像素值,例如设置阈值为100,大于100的像素变成100,小于的变成0或者其他值。其就是将多个像素点变成两个。

二值化操作作用:可以使图像中的数据量大大降低图像的复杂度,并且能够凸显出图像中的轮廓。

CV_EXPORTS_W double threshold( InputArray src, OutputArray dst,double thresh, double maxval, int type );

第一个参数:src源图像,可以是8位灰度图,也可以是32位的三通道图像
第二个参数:dst目标图像

第三个参数:thresh阈值
第四个参数:maxval二值图像中灰度最大值,maxval只能在THRESH_BINARYTHRESH_BINARY_INV有用,但是其他选项也需要填这个值,不能空着。
第五个参数:type阈值操作类型,具体的阈值操作如下图:

1.THRESH_BINARY

作用:二值化阈值处理会将原始图像作为仅有的两个值图像

它针对的像素的处理方式是对于灰度值大于阈值thresh的像素点,将其灰度值设定为maxval最大值。而对于灰度值小于或等于阈值thresh的像素点,将其灰度值设定为0。

2.THRESH_BINARY_INV

作用:反二值化阈值处理也会将原始图像作为仅有的两个值图像,但是它处理的方式和THRESH_BINARY不一样,

它的特点是:对于灰度值大于阈值的像素点,将其设置为0。而对于灰度值小于或者等于阈值的像素点,将这部分的部分设置为maxval最大像素点。

3.THRESH_TRUNC

作用:截断阈值化处理会把图像中大于阈值的像素点设定为阈值,小于或者等于该阈值的像素点保持不变。

比方说阈值设置成127,则说明对于像素超过127的像素点,而其像素值就被设置成127。而小于或者等于127的像素点,其数值保持不变。

4.THRESH_TOZERO

作用:低阈值处理会对图像中小于或者等于阈值的像素点处理为0,大于阈值的像素点则保持不变。

比方说当前阈值设定为127,若当前像素点小于或者等于127则把像素点处理为0;若当前像素点大于127则保持像素点不变。

 5.THRESH_TOZERO_INV

作用:超阈值处理会对图像中大于阈值的像素点处理为0,小于或者等于该阈值的像素点保持不变。

比方说阈值的值设定为127,若当前像素点大于127则把像素点处理为0;若当前像素点小于或者等于阈值的像素点,那么该像素点保持不变

6.THRESH_OTSU

作用:OTSU方法会遍历所有可能的阈值,从而找到一个最佳的阈值。

值得注意的是,在使用OTSU方法的时候需要把阈值设定为0。这个时候,threshold会自动寻找最优的值。

二.这两章的相关API综合应用案例

#include <opencv2/opencv.hpp>
#include <iostream>
#include <vector>using namespace cv;
using namespace std;int main() {// 1. 读取图像并预处理Mat img = imread("objects.jpg");if (img.empty()) {cerr << "Error: Image not found!" << endl;return -1;}Mat gray, binary;cvtColor(img, gray, COLOR_BGR2GRAY);threshold(gray, binary, 128, 255, THRESH_BINARY);// 2. 查找轮廓vector<vector<Point>> contours;vector<Vec4i> hierarchy;findContours(binary, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);// 3. 处理每个轮廓for (size_t i = 0; i < contours.size(); i++) {const auto& cnt = contours[i];// 计算轮廓面积double area = contourArea(cnt);// 计算轮廓周长double perimeter = arcLength(cnt, true);// 紧凑度计算: $C = 4\pi \times \frac{A}{P^2}$double compactness = (area > 0) ? (4 * CV_PI * area) / (perimeter * perimeter) : 0;cout << "轮廓 " << i << " - 面积: " << area << ", 周长: " << perimeter << ", 紧凑度: " << compactness << endl;// 绘制水平外接矩形Rect bRect = boundingRect(cnt);rectangle(img, bRect, Scalar(0, 255, 0), 2);  // 绿色矩形// 绘制旋转矩形RotatedRect rRect = minAreaRect(cnt);Point2f vertices[4];rRect.points(vertices);for (int j = 0; j < 4; j++) {line(img, vertices[j], vertices[(j + 1) % 4], Scalar(0, 0, 255), 2);  // 红色线段}// 绘制面积和周长文本putText(img, format("A:%.1f", area), Point(bRect.x, bRect.y - 10),FONT_HERSHEY_SIMPLEX, 0.5, Scalar(255, 255, 0), 1);putText(img, format("P:%.1f", perimeter), Point(bRect.x, bRect.y - 30),FONT_HERSHEY_SIMPLEX, 0.5, Scalar(255, 0, 255), 1);}// 4. 显示结果imshow("轮廓分析结果", img);waitKey(0);return 0;
}

三.利用OPENCV的API计算轮廓面积

本次的代码例程,我们会结合之前学习的OPENCV轮廓检测和上一节课的面积API,来计算一个矩形的各种面积(包括轮廓面积、最小外接矩形面积、垂直边界面积)。

计算矩形面积的大体流程:

一般要分以下几个比较重要的步骤,分别是:读取图片、把图形进行灰度处理、对灰度图像进行二值处理、调用findContours去查找二值图片形状的轮廓、循环轮廓数量并且调用contourArea计算每个轮廓的曲线面积、然后再计算最小外接矩形面积(minAreaRect)、边界垂直矩形面积的计算(boundingRect)。如下图所示:

#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <iostream>using namespace cv;
using namespace std;int main()
{//step1Mat img =imread("QT.png");//读取QT这张图片//step2Mat gray;cvtColor(img,gray,COLOR_RGB2GRAY);//转成灰度图//step3Mat bin_img;//参数:原图,目标图,阈值,二直图最大灰度值,阈值操作类//THRESH_BINARY_INV:对于灰度值大于阈值的像素点,将其设置为0。//而对于灰度值小于或者等于阈值的像素点,将这部分的部分设置为maxval最大像素点threshold(gray,bin_img,150,255,THRESH_BINARY_INV);//step4  finContours寻找轮廓并获取轮廓数vector<vector<Point>> contours;findContours(bin_img,contours,RETR_EXTERNAL,CHAIN_APPROX_NONE);//查询轮廓//画框Point2f pts[4];for(int i=0;i<contours.size();i++){RotatedRect minRect=minAreaRect(contours[i]); //通过minAreaRect找到最小外接矩形 //将minAreaect获取的外接矩形的四个顶点传到ptsminRect.points(pts);//用line与四个顶点画出外接矩形line(img,pts[0],pts[1],Scalar(0),3);//用line连接p[0]->p[1]line(img,pts[1],pts[2],Scalar(0),3);//用line连接p[1]->p[2]line(img,pts[2],pts[3],Scalar(0),3);//用line连接p[2]->p[3]line(img,pts[3],pts[0],Scalar(0),3);//用line连接p[3]->p[0]//计算外接矩形的面积int minArea=minRect.size.width*minRect.size.height;printf("minArea = %d\n", minArea);//垂直矩形面积计算Rect bArea = boundingRect(contours[i]);//调用boundingRect查找边界矩形//rectangle矩形画框rectangle(img, bArea, Scalar(255,255,0));int boundingArea = bArea.width * bArea.height;//计算边界矩形面积printf("boundingArea = %d\n", boundingArea);//图像本身面积计算double cArea = contourArea(contours[i]);//计算轮廓面积printf("contourArea = %lf\n", cArea);}imwrite("area.jpg", img);
return 0;
}

                        原图                                                       处理后图

相关文章:

  • 论文MR-SVD
  • 从菜鸟到骑士:TypeScript 基础修炼手册
  • 网盘变硬盘挂载软件:百度 / 阿里 / OneDrive 秒变本地磁盘
  • 做题笔记(ctfshow)
  • MCP Resource模块详解
  • 2480: 2020年06月2级T1:计算矩阵边缘元素之和
  • Prefix Caching 详解:实现 KV Cache 的跨请求高效复用
  • 推理式奖励模型:使用自然语言反馈改进强化学习效果
  • Jmeter(四) - 如何在jmeter中创建网络测试计划
  • Java 企业项目中的线程管理策略
  • 图解JavaScript原型:原型链及其分析 | JavaScript图解
  • VBA经典应用69例应用8:利用VBA,预设某个程序在晚上21点运行
  • 【Bluedroid】蓝牙启动之btm_ble_init源码分析
  • java综合项目开发一课一得
  • Linux 用户层 和 内核层锁的实现
  • 跟我学c++中级篇——多线程中的文件处理
  • 《前端面试题:JavaScript 闭包深度解析》
  • DAY 43 训练
  • Tavily 技术详解:为大模型提供实时搜索增强的利器
  • 《最短路(Dijkstra+Heap)》题集
  • 呼伦贝尔网站建设维护/贵州seo技术培训
  • 怎么什么软件可以吧做网站/天津网站策划
  • 做外贸有哪些网站/网站百度不收录
  • 网站建设公司巨头/关键词搜索次数查询
  • 益阳一站式网站建设公司/网络推广运营公司
  • 网络托管/谷歌seo排名