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

【QT常用技术讲解】opencv实现摄像头图像检测并裁剪物体

前言

        本篇是上一篇【QT常用技术讲解】opencv实现指定分辨率打开摄像头的延伸,增加了opencv常见的物体检测及裁剪功能。

效果图

 源码请查看资源,opencv的window环境搭建请看【QT入门到晋级】window opencv安装及引入qtcreator(包含两种qt编译器:MSVC和MinGW)

功能讲解

本篇只讲增加的物体检测、(拍照)裁剪功能。

物体描边

         增加了一个勾选项edgeDetectionCheckBox,方便结合【拍照】功能,截取出裁边/不裁边的图片,物体描边源码如下

void MainWindow::detectAndDrawObjects(cv::Mat &frame)
{cv::Mat gray, blurred, diff;cv::cvtColor(frame, gray, cv::COLOR_BGR2GRAY);cv::GaussianBlur(gray, blurred, cv::Size(5, 5), 0);// 背景初始化if (background.empty()) {blurred.copyTo(background);return;}// 背景减除cv::absdiff(blurred, background, diff);cv::threshold(diff, diff, 30, 255, cv::THRESH_BINARY);//可对255进行调整// 形态学操作,去除噪声cv::Mat kernel = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(5, 5));cv::morphologyEx(diff, diff, cv::MORPH_CLOSE, kernel);cv::morphologyEx(diff, diff, cv::MORPH_OPEN, kernel);// 边缘检测cv::Mat edged;cv::Canny(blurred, edged, 50, 150);// 结合运动检测和边缘检测cv::bitwise_and(edged, edged, edged, diff);// 查找轮廓std::vector<std::vector<cv::Point>> contours;cv::findContours(edged, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);// 计算轮廓的"圆度"作为置信度指标std::vector<std::pair<cv::Rect, double>> detectedObjects;for (size_t i = 0; i < contours.size(); i++) {double area = cv::contourArea(contours[i]);if (area > 500) { // 只处理足够大的轮廓cv::Rect rect = cv::boundingRect(contours[i]);// 计算轮廓的圆度(周长^2/面积)double perimeter = cv::arcLength(contours[i], true);double circularity = (perimeter * perimeter) / (4 * CV_PI * area);// 圆度接近1表示更接近圆形(更可能是真实物体)if (circularity < 2.0) { // 只保留形状较简单的物体detectedObjects.push_back(std::make_pair(rect, circularity));}}}// 按面积排序,选择最大的物体cv::Rect currentRect(0, 0, 0, 0);if (!detectedObjects.empty()) {std::sort(detectedObjects.begin(), detectedObjects.end(),[](const std::pair<cv::Rect, double>& a, const std::pair<cv::Rect, double>& b) {return (a.first.width * a.first.height) > (b.first.width * b.first.height);});currentRect = detectedObjects[0].first;}// 添加到缓冲区recentDetections.push_back(currentRect);if (recentDetections.size() > BUFFER_SIZE) {recentDetections.erase(recentDetections.begin());}// 计算平均位置和大小int avgX = 0, avgY = 0, avgWidth = 0, avgHeight = 0;int validCount = 0;for (const auto& rect : recentDetections) {if (rect.width > 0 && rect.height > 0) { // 只考虑有效检测avgX += rect.x;avgY += rect.y;avgWidth += rect.width;avgHeight += rect.height;validCount++;}}// 如果有有效检测,绘制平滑后的矩形if (validCount > 0) {avgX /= validCount;avgY /= validCount;avgWidth /= validCount;avgHeight /= validCount;cv::Rect smoothedRect(avgX, avgY, avgWidth, avgHeight);cv::rectangle(frame, smoothedRect, cv::Scalar(0, 255, 0), contourThickness);// 显示轮廓面积std::string label = cv::format("Area: %d", avgWidth * avgHeight);cv::putText(frame, label, cv::Point(avgX, avgY - 10),cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 255, 0), 2);}// 缓慢更新背景(每5帧更新一次)static int frameCount = 0;frameCount++;if (frameCount % 5 == 0) {cv::addWeighted(background, 0.95, blurred, 0.05, 0, background);}
}

函数名

功能描述

参数说明

返回值/作用

cv::cvtColor()

颜色空间转换

frame: 输入图像
gray: 输出图像
cv::COLOR_BGR2GRAY: 转换类型

将BGR图像转换为灰度图像

cv::GaussianBlur()

高斯模糊滤波

gray: 输入图像
blurred: 输出图像
cv::Size(5, 5): 核大小
0: 标准差

减少图像噪声和细节

cv::absdiff()

计算绝对差值

blurred: 输入图像1
background: 输入图像2
diff: 输出图像

计算两幅图像的绝对差异

cv::threshold()

图像阈值化

diff: 输入图像
diff: 输出图像
30: 阈值
255: 最大值
cv::THRESH_BINARY: 阈值类型

将图像二值化

cv::getStructuringElement()

创建结构元素

cv::MORPH_ELLIPSE: 形状
cv::Size(5, 5): 大小

返回椭圆形的结构元素

cv::morphologyEx()

形态学操作

diff: 输入图像
diff: 输出图像
cv::MORPH_CLOSE/OPEN: 操作类型
kernel: 结构元素

执行闭运算和开运算

cv::Canny()

Canny边缘检测

blurred: 输入图像
edged: 输出图像
50: 低阈值
150: 高阈值

检测图像中的边缘

cv::bitwise_and()

按位与操作

edged: 输入图像1
edged: 输入图像2
edged: 输出图像
diff: 掩码

结合边缘检测和运动检测结果

cv::findContours()

查找轮廓

edged: 输入图像
contours: 输出轮廓
cv::RETR_EXTERNAL: 检索模式
cv::CHAIN_APPROX_SIMPLE: 近似方法

查找图像中的轮廓

cv::contourArea()

计算轮廓面积

contours[i]: 输入轮廓

返回轮廓的面积

cv::boundingRect()

计算边界矩形

contours[i]: 输入轮廓

返回包含轮廓的最小矩形

cv::arcLength()

计算轮廓周长

contours[i]: 输入轮廓
true: 轮廓是否闭合

返回轮廓的周长

cv::rectangle()

绘制矩形

frame: 目标图像
smoothedRect: 矩形位置和大小
cv::Scalar(0, 255, 0): 颜色
contourThickness: 线宽

在图像上绘制矩形框

cv::putText()

添加文本

frame: 目标图像
label: 文本内容
cv::Point(avgX, avgY - 10): 位置
cv::FONT_HERSHEY_SIMPLEX: 字体
0.5: 字体大小
cv::Scalar(0, 255, 0): 颜色
2: 线宽

在图像上添加文本标签

cv::addWeighted()

图像加权融合

background: 输入图像1
0.95: 权重1
blurred: 输入图像2
0.05: 权重2
0: 伽马值
background: 输出图像

更新背景图像

以上代码做了优化:每5帧更新一次。另外,为了图像稳定,设置了10fps更新一次。(假设图像不是一直在变化,比如高拍仪拍照的场景)

拍照裁剪

void MainWindow::on_captureBtn_clicked()
{if(!capture || !capture->isOpened()) return;cv::Mat frame;*capture >> frame;if(!frame.empty()) {//检查图像矩阵是否为空if(enableObjectDetection) {// 找到主要物体并裁剪cv::Rect mainObject = findMainObject(frame);//查找图像中的主要物体cv::Mat cropped = segmentObject(frame, mainObject);//裁剪图像中的特定区域saveCapturedImage(cropped);//保存图像到文件} else {// 未开启检测时保存整图saveCapturedImage(frame);//保存图像到文件}}
}void MainWindow::saveCapturedImage(const cv::Mat& image)
{// 获取桌面路径QString desktopPath = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);QString timestr = QDateTime::currentDateTime().toString("yyyy_MM_dd_hh_mm_ss");QString fileName = QString("%1/%2.png").arg(desktopPath).arg(timestr);cv::imwrite(fileName.toStdString(), image);QMessageBox::information(this, "提示", "图片保存成功: " + fileName);
}

enableObjectDetection是勾选项edgeDetectionCheckBox的值,通过segmentObject裁剪图像中的特定区域。

篇尾

        以上是在黑色背景版下试验效果比较好。

http://www.dtcms.com/a/457601.html

相关文章:

  • 深圳建网站哪个好网页设计实训总结3000字大学篇
  • 【密码学实战】openHiTLS mac命令行:消息认证码工具
  • 沙井网站建设石林县工程建设个体交易网站
  • Chromium 138 编译指南 - Android 篇:安装构建依赖项(七)
  • asp 绿色环保企业网站源码 v1.1golang 做网站
  • 第4章 C++多线程系统编程精要
  • 绵阳网站怎样做网站设计要交税吗
  • 同ip网站有什么影响网站建设论文500字
  • 基于springboot的家具商城销售系统
  • 手机版网站制作佛山建站软件
  • 厦门南希网站建设微信应用程序开发
  • 【STM32项目开源】基于STM32的智能厨房火灾燃气监控
  • 最新彩虹云商城二开Pro美化版 新增超多功能 全开源
  • 如何制作家具网站东莞设计网站建设方案
  • 商丘做网站的电话怎样建网站最快
  • 安徽住房与城乡建设部网站网站登记备案 个人
  • 嵌入式开发--温度、湿度、气压传感器BME280
  • 基于ZYNQ FPGA+AI+ARM 的卷积神经网络加速器设计
  • 自助建站之星wordpress图片弹出
  • JavaScript-防抖与节流
  • 广西南宁网站建设哪家好网站调用微信数据
  • 专业手机网站建设公司排名wordpress the7打开速度慢
  • 做网站的主要作用设计师培训学费
  • 【大模型】DeepSeek-V3.2-Exp中的DSA稀疏注意力设计
  • Vue组件通信完整教程
  • 代码随想录 637.二叉树的层平均值
  • Spring前置准备(七)——DefaultListableBeanFactory
  • Linux 进程间通信——System V
  • 【Spring Boot】自定义starter
  • 微网站建设网络温州大军建设有限公司网站