1、Qt+opencv 环境搭建
opencv下载:https://opencv.org/releases/
基于QT+cmake编译MinGW版本opencv
QT中使用OpenCV保姆级教程(含编译opencv)
Windows上Qt配置OpenCV(最简单版本无需自己编译-避坑必看)
在 Qt 项目的 .pro 文件中添加以下配置:
cpp
# 添加 OpenCV 头文件路径
INCLUDEPATH += C:/Users/RTT/Desktop/flechazo/02_project/00_flechazo/opencv/opencv/install/include
# 添加 OpenCV 库文件路径
LIBS += -LC:/Users/RTT/Desktop/flechazo/02_project/00_flechazo/opencv/opencv/install/x64/mingw/lib \
-lopencv_calib3d4110 \
-lopencv_core4110 \
-lopencv_dnn4110 \
-lopencv_features2d4110 \
-lopencv_flann4110 \
-lopencv_highgui4110 \
-lopencv_imgcodecs4110 \
-lopencv_imgproc4110 \
-lopencv_ml4110 \
-lopencv_objdetect4110 \
-lopencv_photo4110 \
-lopencv_stitching4110 \
-lopencv_video4110 \
-lopencv_videoio4110
cpp
INCLUDEPATH +=H:\Qt\opencv3.4.0\OpenCV-MinGW-Build-OpenCV-3.4.5\include \
H:\Qt\opencv3.4.0\OpenCV-MinGW-Build-OpenCV-3.4.5\include \
H:\Qt\opencv3.4.0\OpenCV-MinGW-Build-OpenCV-3.4.5\include\opencv2
LIBS +=H:\Qt\opencv3.4.0\OpenCV-MinGW-Build-OpenCV-3.4.5\x86\mingw\bin\libopencv_*.dll
2、实用转换
2.1 mat转QImage
cpp
//值得注意的是,在转化8位3通道的图像时,OpenCV和QImage使用的红蓝通道是相反的,需要使用rgbSwapped方法互换一下
//---------------------------------------------------------------------------------
QImage QCVMatDataCorvent::QCVMat2QImage(const cv::Mat& mat)
{
const unsigned char* data = mat.data;
int width = mat.cols;
int height = mat.rows;
int bytesPerLine = static_cast<int>(mat.step);
switch(mat.type())
{
//8 bit , ARGB
case CV_8UC4:
{
QImage image(data, width, height, bytesPerLine, QImage::Format_ARGB32);
return image;
}
//8 bit BGR
case CV_8UC3:
{
QImage image(data, width, height, bytesPerLine, QImage::Format_RGB888);
//swap blue and red channel
return image.rgbSwapped();
}
//8 bit Gray shale
case CV_8UC1:
{
QImage image(data, width, height, bytesPerLine, QImage::Format_Grayscale8);
return image;
}
//
default:
{
//Unsupported format
qWarning()<<"Unsupported cv::Mat type:"<<mat.type()
<<", Empty QImage will be returned!";
return QImage();
}
}
}
cpp
cv::Mat imgMat = cv::imread(imgPath.toStdString().c_str());
QImage img = QCVMatDataCorvent::QCVMat2QImage(imgMat);
ui->ImgLabel->setPixmap(QPixmap::fromImage(img));
resize(width()-ui->ImgLabel->width()+img.width(),
height()-ui->ImgLabel->height()+img.height());
2.2 红绿灯检测
【C++】OpenCV:红绿灯检测介绍及实现示例
【交通灯】红绿灯识别 轮廓识别 C++ OpenCV 案例实现(好)
OpenCV中的findContours函数参数详解
最简方法:
在C++中使用OpenCV进行红绿灯检测,可以通过颜色空间分割与轮廓分析实现,不依赖深度学习即可获得较好效果。
步骤说明
- 读取与预处理图像
- 使用 cv::VideoCapture 读取视频帧或图片。
- 转换为 HSV颜色空间,便于分离红色与绿色区域。
- 颜色阈值分割
- 定义红色与绿色的HSV范围,使用 cv::inRange 提取对应颜色区域。
- 对红色需考虑两个Hue区间(低端和高端)。
- 形态学处理去噪
-使用 cv::erode 和 cv::dilate 去除小噪点,保留主要目标区域。- 轮廓检测与筛选
- 使用 cv::findContours 获取轮廓,根据面积、形状筛选可能的红绿灯区域。
- 状态判断
- 根据检测到的颜色区域位置与大小,判断当前状态为 红灯、绿灯或无灯。
cpp
#include <opencv2/opencv.hpp>
using namespace cv;
int main() {
Mat frame, hsv, maskRed1, maskRed2, maskGreen;
VideoCapture cap("traffic_light.mp4");
while (cap.read(frame)) {
cvtColor(frame, hsv, COLOR_BGR2HSV);
Scalar lowerRed1(0, 100, 100), upperRed1(10, 255, 255);
Scalar lowerRed2(160, 100, 100), upperRed2(179, 255, 255);
Scalar lowerGreen(35, 100, 100), upperGreen(85, 255, 255);
inRange(hsv, lowerRed1, upperRed1, maskRed1);
inRange(hsv, lowerRed2, upperRed2, maskRed2);
inRange(hsv, lowerGreen, upperGreen, maskGreen);
Mat redMask = maskRed1 | maskRed2;
morphologyEx(redMask, redMask, MORPH_OPEN, Mat());
morphologyEx(maskGreen, maskGreen, MORPH_OPEN, Mat());
if (countNonZero(redMask) > countNonZero(maskGreen))
putText(frame, "RED", {50,50}, FONT_HERSHEY_SIMPLEX, 1, Scalar(0,0,255), 2);
else if (countNonZero(maskGreen) > 0)
putText(frame, "GREEN", {50,50}, FONT_HERSHEY_SIMPLEX, 1, Scalar(0,255,0), 2);
imshow("Traffic Light Detection", frame);
if (waitKey(30) == 27) break;
}
}