最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Qt+Opencv實(shí)現(xiàn)梯度矯正功能

 更新時(shí)間:2024年04月10日 08:21:56   作者:十一的雜文錄  
這篇文章主要為大家詳細(xì)介紹了Qt如何結(jié)合Opencv實(shí)現(xiàn)梯度矯正功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

廢話:

有時(shí)候我們是從物品的斜上方拍攝的圖片,看起來(lái)不直觀,需要把視角拉正,這樣的一個(gè)操作就叫做 梯度矯正,需要用到的技術(shù)是 Opencv 的透視變換。

這個(gè)只是一個(gè)簡(jiǎn)單的演示demo,如果完善一下,比如物品檢測(cè),可以應(yīng)用更多的場(chǎng)景,比如常見(jiàn)的:文件、資料上傳,軟管攝像頭的應(yīng)用等,怎么說(shuō)也是一個(gè)技術(shù)點(diǎn)吧

重要代碼

/**
* @brief hDLL_gradientAuto 梯度矯正
* @param src  輸入圖像
* @param dst  輸出圖像
* @param flag 方向,[0(左),1(上),2(右),3(下)]
* @param val  矯正度數(shù),像素,[10 ~ 100]
* @return 0(成功),-1(失敗)
*/ 
int MainWindow::hDLL_gradientAuto(Mat &src, Mat &dst, int flag, int val)
{
    if(flag != 0 && flag != 1 && flag != 2 && flag != 3) return -1;
    if(val < 10 || val > 100) return -1;

    int width = src.cols;
    int height = src.rows;
    Mat M;
    // flag 方向,[0(左),1(上),2(右),3(下)]
    switch (flag) {
    case 0:
    {
        Point2f pts_src[] = { Point(val,val), Point(width, 0), Point(width, height), Point(val, height-val)};
        Point2f pts_dst[] = { Point(0, 0), Point(width, 0), Point(width, height) ,Point(0, height) };
        M = cv::getPerspectiveTransform(pts_src, pts_dst);
    }break;
    case 1:
    {
        Point2f pts_src[] = { Point(val,val), Point(width-val, val), Point(width, height), Point(0, height)};
        Point2f pts_dst[] = { Point(0, 0), Point(width, 0), Point(width, height) ,Point(0, height) };
        M = cv::getPerspectiveTransform(pts_src, pts_dst);
    }break;
    case 2:
    {
        Point2f pts_src[] = { Point(0,0), Point(width-val, val), Point(width-val, height-val), Point(0, height)};
        Point2f pts_dst[] = { Point(0, 0), Point(width, 0), Point(width, height) ,Point(0, height) };
        M = cv::getPerspectiveTransform(pts_src, pts_dst);
    }break;
    case 3:
    {
        Point2f pts_src[] = { Point(0,0), Point(width, 0), Point(width-val, height-val), Point(val, height-val)};
        Point2f pts_dst[] = { Point(0, 0), Point(width, 0), Point(width, height) ,Point(0, height) };
        M = cv::getPerspectiveTransform(pts_src, pts_dst);
    }break;
    }

    cv::warpPerspective(src, dst, M, dst.size(), cv::INTER_LINEAR , cv::BORDER_REPLICATE);
    return 0;
}

Demo演示

完整代碼

.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QImage>
#include <QDebug>
#include <QtMath>

#include "opencv2/opencv.hpp"
using namespace cv;

QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

    void updateQLabelImage();

    Mat QImage2Mat(QImage &img);
    QImage Mat2QImage(Mat &img);

    /**
     * @brief hDLL_gradientAuto 梯度矯正
     * @param src  輸入圖像
     * @param dst  輸出圖像
     * @param flag 方向,[0(左),1(上),2(右),3(下)]
     * @param val  矯正度數(shù),像素,[10 ~ 100]
     * @return 0(成功),-1(失敗)
     */
    int hDLL_gradientAuto(Mat &src, Mat &dst, int flag, int val);

public slots:
    void horChange(int index);
    void verChange(int index);

private:
    Ui::MainWindow *ui;

    QImage m_img;       // 原圖
    QImage m_img_dst;   // 處理過(guò)的圖像
};
#endif // MAINWINDOW_H

.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    connect(ui->horizontalSlider, SIGNAL(valueChanged(int)), this, SLOT(horChange(int)));
    connect(ui->verticalSlider, SIGNAL(valueChanged(int)), this, SLOT(verChange(int)));

    m_img = QImage("F:1.jpg");
    m_img_dst = m_img;
    updateQLabelImage();
}

MainWindow::~MainWindow()
{
    delete ui;
}

// 更新QLabel里面的圖像
void MainWindow::updateQLabelImage()
{
    // m_img = m_img.scaled(ui->label->width(), ui->label->height());
    QImage img_show = m_img_dst.scaled(ui->label->width(), ui->label->height());
    ui->label->setPixmap(QPixmap::fromImage(img_show));
}

Mat MainWindow::QImage2Mat(QImage &img)
{
    cv::Mat mat;
    switch (img.format())
    {
    case QImage::Format_RGB32:  //一般Qt讀入彩色圖后為此格式
        mat = cv::Mat(img.height(), img.width(), CV_8UC4, (void*)img.constBits(), img.bytesPerLine());
        cv::cvtColor(mat,mat,cv::COLOR_BGRA2BGR);   //轉(zhuǎn)3通道
        break;
    case QImage::Format_RGB888:
        mat = cv::Mat(img.height(), img.width(), CV_8UC3, (void*)img.constBits(), img.bytesPerLine());
        cv::cvtColor(mat,mat,cv::COLOR_RGB2BGR);
        break;
    case QImage::Format_Indexed8:
        mat = cv::Mat(img.height(), img.width(), CV_8UC1, (void*)img.constBits(), img.bytesPerLine());
        break;
    }
    return mat;
}

QImage MainWindow::Mat2QImage(Mat &img)
{
    if(img.type()==CV_8UC1 || img.type()==CV_8U)
    {
        QImage image((const uchar *)img.data, img.cols, img.rows, img.step, QImage::Format_Grayscale8);
        return image;
    }
    else if(img.type()==CV_8UC3)
    {
        QImage image((const uchar *)img.data, img.cols, img.rows, img.step, QImage::Format_RGB888);
        return image.rgbSwapped();  //r與b調(diào)換
    }
}

int MainWindow::hDLL_gradientAuto(Mat &src, Mat &dst, int flag, int val)
{
    if(flag != 0 && flag != 1 && flag != 2 && flag != 3) return -1;
    if(val < 10 || val > 100) return -1;

    int width = src.cols;
    int height = src.rows;
    Mat M;
    // flag 方向,[0(左),1(上),2(右),3(下)]
    switch (flag) {
    case 0:
    {
        Point2f pts_src[] = { Point(val,val), Point(width, 0), Point(width, height), Point(val, height-val)};
        Point2f pts_dst[] = { Point(0, 0), Point(width, 0), Point(width, height) ,Point(0, height) };
        M = cv::getPerspectiveTransform(pts_src, pts_dst);
    }break;
    case 1:
    {
        Point2f pts_src[] = { Point(val,val), Point(width-val, val), Point(width, height), Point(0, height)};
        Point2f pts_dst[] = { Point(0, 0), Point(width, 0), Point(width, height) ,Point(0, height) };
        M = cv::getPerspectiveTransform(pts_src, pts_dst);
    }break;
    case 2:
    {
        Point2f pts_src[] = { Point(0,0), Point(width-val, val), Point(width-val, height-val), Point(0, height)};
        Point2f pts_dst[] = { Point(0, 0), Point(width, 0), Point(width, height) ,Point(0, height) };
        M = cv::getPerspectiveTransform(pts_src, pts_dst);
    }break;
    case 3:
    {
        Point2f pts_src[] = { Point(0,0), Point(width, 0), Point(width-val, height-val), Point(val, height-val)};
        Point2f pts_dst[] = { Point(0, 0), Point(width, 0), Point(width, height) ,Point(0, height) };
        M = cv::getPerspectiveTransform(pts_src, pts_dst);
    }break;
    }

    cv::warpPerspective(src, dst, M, dst.size(), cv::INTER_LINEAR , cv::BORDER_REPLICATE);
    return 0;
}

// 橫向改變
void MainWindow::horChange(int index)
{
    qDebug() << "hor:" << index;

    if(index == 0)
    {
        m_img_dst = m_img;
    }
    else if(index < 0)
    {
        int val = abs(index) * 10;
        Mat src = QImage2Mat(m_img);
        Mat dst;
        hDLL_gradientAuto(src, dst, 0, val);
        m_img_dst = Mat2QImage(dst);
    }
    else if (index > 0)
    {
        int val = abs(index) * 10;
        Mat src = QImage2Mat(m_img);
        Mat dst;
        hDLL_gradientAuto(src, dst, 2, val);
        m_img_dst = Mat2QImage(dst);
    }
    updateQLabelImage();
}

// 豎向改變
void MainWindow::verChange(int index)
{
    qDebug() << "ver:" << index;

    if(index == 0)
    {
        m_img_dst = m_img;
    }
    else if(index < 0)
    {
        int val = abs(index) * 10;
        Mat src = QImage2Mat(m_img);
        Mat dst;
        hDLL_gradientAuto(src, dst, 3, val);
        m_img_dst = Mat2QImage(dst);
    }
    else if (index > 0)
    {
        int val = abs(index) * 10;
        Mat src = QImage2Mat(m_img);
        Mat dst;
        hDLL_gradientAuto(src, dst, 1, val);
        m_img_dst = Mat2QImage(dst);
    }

    updateQLabelImage();
}

環(huán)境是:Qt 5.15.2 + Opencv V4.8.0,如果需要下載代碼,自己調(diào)試,自己配置環(huán)境即可

代碼倉(cāng)庫(kù):https://gitee.com/vvvj/qt-test-gradient-auto

以上就是Qt+Opencv實(shí)現(xiàn)梯度矯正功能的詳細(xì)內(nèi)容,更多關(guān)于Qt Opencv梯度矯正的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C語(yǔ)言實(shí)現(xiàn)手機(jī)電話簿管理系統(tǒng)

    C語(yǔ)言實(shí)現(xiàn)手機(jī)電話簿管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)手機(jī)電話簿管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • OpenCV實(shí)現(xiàn)圖像腐蝕

    OpenCV實(shí)現(xiàn)圖像腐蝕

    這篇文章主要為大家詳細(xì)介紹了OpenCV實(shí)現(xiàn)圖像腐蝕,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-06-06
  • C語(yǔ)言實(shí)例上手深入理解操作符的使用

    C語(yǔ)言實(shí)例上手深入理解操作符的使用

    C 語(yǔ)言提供了豐富的操作符,有:算術(shù)操作符,移位操作符,位操作符,賦值操作符,單目操作符,關(guān)系操作符,邏輯操作符,條件操作符等。接下了讓我們?cè)趯?shí)例中練一下
    2022-05-05
  • C++ 中類的拷貝、賦值、銷毀的實(shí)例詳解

    C++ 中類的拷貝、賦值、銷毀的實(shí)例詳解

    這篇文章主要介紹了C++ 中類的拷貝、賦值、銷毀的實(shí)例詳解的相關(guān)資料,希望通過(guò)本文能幫助到大家,需要的朋友可以參考下
    2017-09-09
  • Inline Hook(ring3)的簡(jiǎn)單C++實(shí)現(xiàn)方法

    Inline Hook(ring3)的簡(jiǎn)單C++實(shí)現(xiàn)方法

    這篇文章主要介紹了Inline Hook(ring3)的簡(jiǎn)單C++實(shí)現(xiàn)方法,需要的朋友可以參考下
    2014-08-08
  • Qt使用QCustomPlot的實(shí)現(xiàn)示例

    Qt使用QCustomPlot的實(shí)現(xiàn)示例

    QCustomPlot是一個(gè)基于Qt C++的圖形庫(kù),用于繪制和數(shù)據(jù)可視化,并為實(shí)時(shí)可視化應(yīng)用程序提供高性能服務(wù),本文主要介紹了Qt使用QCustomPlot的實(shí)現(xiàn)示例,感興趣的可以了解一下
    2024-01-01
  • 基于C語(yǔ)言實(shí)現(xiàn)學(xué)生選課系統(tǒng)

    基于C語(yǔ)言實(shí)現(xiàn)學(xué)生選課系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了基于C語(yǔ)言實(shí)現(xiàn)學(xué)生選課系統(tǒng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-02-02
  • C語(yǔ)言鏈表與單鏈表詳解

    C語(yǔ)言鏈表與單鏈表詳解

    鏈表是一種物理存儲(chǔ)結(jié)構(gòu)上非連續(xù)、非順序的存儲(chǔ)結(jié)構(gòu),數(shù)據(jù)元素的邏輯順序是通過(guò)鏈表中的指針鏈接次序?qū)崿F(xiàn)的,本章帶你詳細(xì)了解鏈表與單鏈表
    2022-02-02
  • C++實(shí)現(xiàn)簡(jiǎn)單學(xué)生信息管理系統(tǒng)

    C++實(shí)現(xiàn)簡(jiǎn)單學(xué)生信息管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)簡(jiǎn)單學(xué)生信息管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • C語(yǔ)言用函數(shù)實(shí)現(xiàn)反彈球消磚塊

    C語(yǔ)言用函數(shù)實(shí)現(xiàn)反彈球消磚塊

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言用函數(shù)實(shí)現(xiàn)反彈球消磚塊,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-05-05

最新評(píng)論

保定市| 萨嘎县| 西乡县| 高邮市| 岱山县| 南汇区| 宣城市| 察隅县| 麻江县| 平江县| 方正县| 边坝县| 定日县| 商洛市| 清远市| 英山县| 明水县| 渭南市| 无棣县| 大庆市| 安远县| 罗江县| 正镶白旗| 越西县| 鄂托克旗| 德保县| 宁晋县| 九台市| 长岭县| 托克逊县| 会昌县| 固阳县| 彰化县| 农安县| 甘德县| 峨山| 石狮市| 肥东县| 瑞昌市| 东至县| 宣威市|