概述
#ifndef IMAGEPROC_H
#define IMAGEPROC_H
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <QImage>
#include <QThread>
#include <iostream>
#include "BadPointDetector.h"
#include <QPoint>
using namespace cv;
class ImageProc: public QObject
{
Q_OBJECT
public:
ImageProc();
void readImg();
void readImg(QString imgPath, QImage &desImg, QImage::Format format);
QImage mat2qimage_ref(cv::Mat &m, QImage::Format format);
QImage mat2qimage_cpy(cv::Mat &m, QImage::Format format);
signals:
void sig_frameStream(QImage);
void sig_keyPoints(std::vector<QPoint>);
public slots:
void slot_openCamera(); // 打开本地摄像头 0
void slot_closeCamera();
private:
std::vector<cv::KeyPoint> m_keyPoints;
cv::VideoCapture m_camera;
BadPointDetector m_badPointDetector;
bool m_videoState;
};
#endif // IMAGEPROC_H
#include "ImageProc.h"
#include "opencv2/imgproc.hpp"
#include <QDebug>
ImageProc::ImageProc()
{
}
void ImageProc::readImg()
{
cv::Mat srcImage;
srcImage = imread("D:\code\TestOpenCV\iamge\m2.jpeg", IMREAD_COLOR);
if (srcImage.empty()) {
return;
}
namedWindow("orginalimage", WINDOW_AUTOSIZE);
imshow("orginal image", srcImage);
// Shallow copy
// Shallow copy
}
void ImageProc::readImg(QString imgPath, QImage &desImg, QImage::Format format)
{
cv::Mat srcImage;
srcImage = imread(imgPath.toStdString(), IMREAD_COLOR);
desImg = mat2qimage_cpy(srcImage, format);
}
// 线程单独读取数据
void ImageProc::slot_openCamera()
{
cv::VideoCapture m_camera(0);
if (true == m_camera.isOpened()) {
m_videoState = true;
while (m_videoState) {
cv::Mat frame;
//qDebug() << "capture one frame." << "current thread id=" << QThread::currentThreadId();
m_camera >> frame;
// 检测角点坐标列表
m_badPointDetector.getFastFeatureDetector(frame, 20, m_keyPoints);
std::vector<QPoint> tmpPoints;
foreach (cv::KeyPoint it, m_keyPoints) {
tmpPoints.push_back(QPoint(it.pt.x, it.pt.y));
}
emit sig_keyPoints(tmpPoints);
// 发送到界面
emit sig_frameStream(mat2qimage_cpy(frame, QImage::Format_RGB888));
}
}
}
void ImageProc::slot_closeCamera()
{
m_camera.release();
m_videoState = false;
qDebug() << "close camera";
return;
}
QImage ImageProc::mat2qimage_ref(cv::Mat &m, QImage::Format format)
{
return QImage(m.data, m.cols, m.rows, (int)m.step, format);
}
// Deep copy
QImage ImageProc::mat2qimage_cpy(cv::Mat &m, QImage::Format format)
{
cv::cvtColor(m, m, COLOR_BGR2RGB); // cv 默认图像格式 BGR,不然显示颜色顺序不对
return QImage(m.data, m.cols, m.rows, (int)m.step, format).copy();
}
#ifndef BADPOINTDETECTOR_H
#define BADPOINTDETECTOR_H
#include <opencv2core.hpp>
#include <opencv2highguihighgui.hpp>
#include <opencv2imgprocimgproc.hpp>
#include <opencv2features2d.hpp>
#include <string.h>
#include <QImage>
#include <QObject>
#include <iostream>
using namespace std;
class BadPointDetector: public QObject
{
Q_OBJECT
public:
BadPointDetector();
// int getCornerPosList(cv::Mat&, cv::Point2d&);
bool loadSrcImage(const string &name);
bool loadSrcImage(const cv::Mat m);
void setThreshold(double threshold, double high); // 对外用户调参接口。控制角点检测准确性
cv::Mat getDstImage();
cv::Mat getDstImageByCanny(double low , double high);
void getFastFeatureDetector(cv::Mat srcImg, int ketPoints, std::vector<cv::KeyPoint> &keypoints);
std::vector<QPoint> getKeyPoints(); // 获取检测角点
signals:
void sig_updateImg(QImage newFrame); //更新界面窗口显示的图像需要的数据
private:
cv::Mat m_srcImage;
cv::Mat m_dstImage;
double m_threshold;
};
#endif // BADPOINTDETECTOR_H
#include "BadPointDetector.h"
#include <QDebug>
BadPointDetector::BadPointDetector()
{
cv::Mat image1= cv::imread("D:/code/TestOpenCV/images/myImage/color2.jpg", cv::IMREAD_GRAYSCALE);
// cv::Mat image1= cv::imread("D:/code/TestOpenCV/images/images/church02.jpg", cv::IMREAD_GRAYSCALE);
m_srcImage = image1;
// cv::namedWindow("SRC_IMAGE");
// cv::imshow("SRC_IMAGE", image1);
QImage newImg(m_srcImage.cols, m_srcImage.rows, QImage::Format_Indexed8);
emit sig_updateImg(newImg);
cv::Mat cornerStrength;
cv::cornerHarris(image1,
cornerStrength,
3,
3,
0.001);
cv::Mat harrisCorners; //角点强度图像
// double threshold = 0.001;
double threshold = 100;
cv::threshold(cornerStrength,
harrisCorners,
threshold,
255,
cv::THRESH_BINARY_INV);
// cv::namedWindow("harrisCorner");
//cv::imshow("harrisCorner", cornerStrength);
}
//int BadPointDetector::getCornerPosList(cv::Mat &srcImg, cv::Point2d &posLits)
//{
// if (!loadSrcImage(srcImg)) {
// return -1;
// }
// getDstImage();
// return 0;
//}
bool BadPointDetector::loadSrcImage(const string &name)
{
m_srcImage = cv::imread((name), 0);
if (!m_srcImage.data) {
return false;
}
return true;
}
//bool BadPointDetector::loadSrcImage(const cv::Mat m)
//{
// if (m.data == nullptr) {
// return false;
// }
// m_srcImage = m;
// return true;
//}
void BadPointDetector::setThreshold(double threshold , double high)
{
qDebug() <<"srcImageSize=" <<*m_srcImage.size <<"threshold=" << threshold;
if (!*m_srcImage.size || threshold==NULL) {
return;
}
m_threshold = threshold;
qDebug() << "threshold = "<< m_threshold;
cv::Mat dstCVImg = getDstImageByCanny(threshold, high);
QImage qimage(dstCVImg.cols, dstCVImg.rows, QImage::Format_Grayscale8);
emit sig_updateImg(qimage);
}
cv::Mat BadPointDetector::getDstImage()
{
cv::Mat cornerStrength;
cv::cornerHarris(m_srcImage, // 必须是单通道的图像
cornerStrength,
3,
3,
0.004); //经验参数,取值范围 0.04 ~ 0.06
cv::threshold(cornerStrength,
m_dstImage,
m_threshold,
255,
cv::THRESH_BINARY_INV);
return m_dstImage;
}
cv::Mat BadPointDetector::getDstImageByCanny(double low , double high)
{
cv::Canny(m_srcImage, // 灰度图像
m_dstImage, // 输出轮廓
low, // 低阈值
high); // 高阈值
return m_dstImage;
}
void BadPointDetector::getFastFeatureDetector(cv::Mat srcImg, int ketPoints, std::vector<cv::KeyPoint> &keypoints)
{
m_srcImage = srcImg;
// FAST 特征检测器,阈值为 40
cv::Ptr<cv::FastFeatureDetector> ptrFAST = cv::FastFeatureDetector::create(ketPoints);
// 检测关键点
ptrFAST->detect(m_srcImage, keypoints);
cv::drawKeypoints(m_srcImage, // 原始图像
keypoints, // 关键点的向量
m_srcImage, // 输出图像
cv::Scalar(255,255,255), // 关键点的颜色
cv::DrawMatchesFlags::DRAW_OVER_OUTIMG); // 画图标志
}
界面
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QThread>
#include <QDebug>
#include <QTimer>
#include <QPainter>
#include "BadPointDetector.h"
#include "ImageProc.h"
#include "PointsForm.h"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
signals:
void sig_openCamera();
void sig_closeCamera();
private slots:
void on_pushButtonOpen_clicked();
void slot_showImg(QImage img);
void slot_changeThreshold();
void slot_showKeyPoint(std::vector<QPoint>);
void on_pushButtonShowPoints_clicked();
private:
Ui::MainWindow *ui;
ImageProc *m_imgProc;
QThread *m_videoReadThd;
QTimer m;
BadPointDetector m_badPointDetector;
QPixmap m_labelPixMap;
PointsForm m_pointsTable;
};
#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->pushButtonOpen->setText("open");
m_videoReadThd = new QThread;
m_imgProc = new ImageProc;
m_imgProc->moveToThread(m_videoReadThd);
m_videoReadThd->start();
connect(this, &MainWindow::sig_openCamera, m_imgProc, &ImageProc::slot_openCamera);
connect(this, &MainWindow::sig_closeCamera, m_imgProc, &ImageProc::slot_closeCamera);
connect(m_imgProc, &ImageProc::sig_frameStream, this, &MainWindow::slot_showImg);
connect(ui->lineEditThreshold, &QLineEdit::editingFinished, this, &MainWindow::slot_changeThreshold);
connect(&m_badPointDetector, &BadPointDetector::sig_updateImg, this, &MainWindow::slot_showImg);
connect(m_imgProc, &ImageProc::sig_keyPoints, this, &MainWindow::slot_showKeyPoint);
}
MainWindow::~MainWindow()
{
delete ui;
m_imgProc->deleteLater();
}
void MainWindow::on_pushButtonOpen_clicked()
{
// 打开camnera 设备
if (ui->pushButtonOpen->text() == "open") {
ui->pushButtonOpen->setText("close"); // 必须使用信号启动
emit sig_openCamera();
}
else if (ui->pushButtonOpen->text() == "close") { // close camera
ui->pushButtonOpen->setText("open");
// m_imgProc->slot_closeCamera();
emit sig_closeCamera();
}
}
void MainWindow::slot_showImg(QImage img)
{
m_labelPixMap.convertFromImage(img);
ui->labelImg->setPixmap(m_labelPixMap);
}
void MainWindow::slot_changeThreshold()
{
qDebug() << "change threshold.";
double thresholdTmp = (ui->lineEditThreshold->text()).toDouble();
m_badPointDetector.setThreshold(thresholdTmp, ui->lineEditThresholdHigh->text().toDouble());
}
void MainWindow::slot_showKeyPoint(std::vector<QPoint> points)
{
//在 table 展示坐标
QAction act;
act.data() = 0;
m_pointsTable.addAction(&act);
}
void MainWindow::on_pushButtonShowPoints_clicked()
{
m_pointsTable.show();
}
最后
以上就是花痴学姐为你收集整理的Qt OpenCV 快速角点校测的全部内容,希望文章能够帮你解决Qt OpenCV 快速角点校测所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复