QT+opencv进行图像圆的识别,且对圆进行颜色识别
一、 环境
windows版本: win10 x64
Opencv版本: 3.4.5
QT版本:5.12
二、Opencv下载
官网地址opencv下载地址
三、QT新建工程,在.pro工程添加opencv路径
INCLUDEPATH += \
D:\opencv\build\include\opencv2 \
D:\opencv\build\include\opencv \
D:\opencv\build\include
LIBS += \
D:\opencv\build\x64\vc15\lib\opencv_world345.lib \
D:\opencv\build\x64\vc15\lib\opencv_world345d.lib
路径根据自己安装位置不同自行修改
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
using namespace cv;
六、程序思路是每30ms进行一帧图像采集并识别,需要使用QTimer,每30ms触发一次信号。
mytimer_capture = new QTimer(this);
connect(mytimer_capture,&QTimer::timeout,this,&Widget::mytimer_capture_slot);
mytimer_capture->start(30);
七、打开相机
capture.open(1);
if (capture.isOpened()) {
qDebug()<<"camera open!!!";
}
八、opencv使用的图片是Mat类,QT显示是QImage,我们需要一个转换函数
// 图片转换(网上抄的)
QImage Widget::Mat2QImage(Mat cvImg)
{
QImage qImg;
if(cvImg.channels()==3) //3 channels color image
{
cv::cvtColor(cvImg,cvImg,CV_BGR2RGB);
qImg =QImage((const unsigned char*)(cvImg.data),
cvImg.cols, cvImg.rows,
cvImg.cols*cvImg.channels(),
QImage::Format_RGB888);
}
else if(cvImg.channels()==1) //grayscale image
{
qImg =QImage((const unsigned char*)(cvImg.data),
cvImg.cols,cvImg.rows,
cvImg.cols*cvImg.channels(),
QImage::Format_Indexed8);
}
else
{
qImg =QImage((const unsigned char*)(cvImg.data),
cvImg.cols,cvImg.rows,
cvImg.cols*cvImg.channels(),
QImage::Format_RGB888);
}
return qImg;
}
九、定时器槽函数实现从相机取一帧图像,函数
void Widget::mytimer_capture_slot()
{
Mat frame; //定义一个Mat变量,用于存储每一帧的图像
capture>>frame; //读取当前帧
if (!frame.empty()) { //判断当前帧是否捕捉成功 **这步很重要
SearchCircle(frame);
}
}
十、SearchCircle是寻找圆并进行颜色识别
void Widget::SearchCircle(Mat &matSrc)
{
Mat grayImg;
cv::cvtColor(matSrc, grayImg, CV_BGR2GRAY);//生成灰度图,提高检测效率
cv::medianBlur(grayImg, grayImg,5);
std::vector<Vec3f> circles;//存储每个圆的位置信息
//霍夫圆
cv::HoughCircles(grayImg, circles, CV_HOUGH_GRADIENT, 1,
houghCircles_para.min_dist,
houghCircles_para.param1,
houghCircles_para.param2,
houghCircles_para.min_radius,
houghCircles_para.max_radius);
for (size_t i = 0; i < circles.size(); i++) {
Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
int radius = cvRound(circles[i][2]);
//绘制圆轮廓
circle(matSrc, center, radius, cv::Scalar(155, 50, 255), 3, 8, 0);
cv::Point textpoint;
textpoint.x = center.x + radius;
textpoint.y = center.y - radius;
int font_face = cv::FONT_HERSHEY_COMPLEX;
double font_scale = 1;
int thickness = 1;
std::string text = ColorGet(matSrc,center).toStdString();
ui->lbl_ccolor->setText(QString::fromStdString(text));
cv::putText(matSrc, text, textpoint, font_face, font_scale, cv::Scalar(0, 0, 255), thickness, 8, 0);
}
QImage image = Mat2QImage(matSrc);
ui->lbl_videoshow->setPixmap(QPixmap::fromImage(image));
ui->lbl_videoshow->resize(image.size());
}
十一、颜色识别使用HSV域,具体可参考https://blog.csdn.net
QString Widget::ColorGet(Mat &matSrc,Point &origin)
{
Mat matHsv;
cvtColor(matSrc,matHsv,COLOR_BGR2HSV);
vector<int> colorVec;
colorVec.push_back(matHsv.at<Vec3b>(origin.y,origin.x)[0]);
colorVec.push_back(matHsv.at<Vec3b>(origin.y,origin.x)[1]);
colorVec.push_back(matHsv.at<Vec3b>(origin.y,origin.x)[2]);
if((colorVec[0]>=0&&colorVec[0]<=180)
&&(colorVec[1]>=0&&colorVec[1]<=255)
&&(colorVec[2]>=0&&colorVec[2]<=46)){
return "black";
}
else if((colorVec[0]>=0&&colorVec[0]<=180)
&&(colorVec[1]>=0&&colorVec[1]<=43)
&&(colorVec[2]>=46&&colorVec[2]<=220)){
return "gray";
}
else if((colorVec[0]>=0&&colorVec[0]<=180)
&&(colorVec[1]>=0&&colorVec[1]<=30)
&&(colorVec[2]>=221&&colorVec[2]<=255)){
return "white";
}
else if(((colorVec[0]>=0&&colorVec[0]<=10)||(colorVec[0]>=156&&colorVec[0]<=180))
&&(colorVec[1]>=43&&colorVec[1]<=255)
&&(colorVec[2]>=46&&colorVec[2]<=255)){
return "red";
}
else if((colorVec[0]>=11&&colorVec[0]<=25)
&&(colorVec[1]>=43&&colorVec[1]<=255)
&&(colorVec[2]>=46&&colorVec[2]<=255)){
return "orange";
}
else if((colorVec[0]>=26&&colorVec[0]<=34)
&&(colorVec[1]>=43&&colorVec[1]<=255)
&&(colorVec[2]>=46&&colorVec[2]<=255)){
return "yellow";
}
else if((colorVec[0]>=35&&colorVec[0]<=77)
&&(colorVec[1]>=43&&colorVec[1]<=255)
&&(colorVec[2]>=46&&colorVec[2]<=255)){
return "green";
}
else if((colorVec[0]>=78&&colorVec[0]<=99)
&&(colorVec[1]>=43&&colorVec[1]<=255)
&&(colorVec[2]>=46&&colorVec[2]<=255)){
return "green";
}
else if((colorVec[0]>=100&&colorVec[0]<=124)
&&(colorVec[1]>=43&&colorVec[1]<=255)
&&(colorVec[2]>=46&&colorVec[2]<=255)){
return "blue";
}
else if((colorVec[0]>=125&&colorVec[0]<=155)
&&(colorVec[1]>=43&&colorVec[1]<=255)
&&(colorVec[2]>=46&&colorVec[2]<=255)){
return "purple";
}
else{
return "nop";
}
}