亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

OpenCV實現(xiàn)亂序碎片復(fù)原

 更新時間:2021年12月24日 15:36:00   作者:Zane Zeng  
這篇文章主要介紹了通過OpenCV 直方圖相似度對比,實現(xiàn)將4張打亂順序的碎片拼接復(fù)原并展示原圖。文中的示例代碼講解詳細(xì),需要的朋友可以學(xué)習(xí)一下

題目

將4張打亂順序的碎片拼接復(fù)原并展示原圖

算法思路

將x張碎片的左右邊緣提取保存

左右邊緣兩兩對比,將相似度超過預(yù)設(shè)閾值的碎片執(zhí)行拼接操作,得到左右拼接好的碎片

提取左右拼接好的碎片的上下邊緣

上下邊緣兩兩對比,將相似度超過預(yù)設(shè)閾值的碎片執(zhí)行拼接操作,得到原圖

源碼展示

#include <opencv2/opencv.hpp>
#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
#include <string>
#include <cstdlib>
#include <utility>
#include <opencv2/imgproc/types_c.h>

using namespace std;
using namespace cv;

/*
 * 問題: 將x張打亂順序的碎片復(fù)原,將復(fù)原好的圖片展示出來
 * 思路: 1. 將x張碎片的左右邊緣提取保存
 *       2. 左右邊緣兩兩對比,將相似度超過預(yù)設(shè)閾值的碎片執(zhí)行拼接操作,得到左右拼接好的碎片
 *       3. 提取左右拼接好的碎片的上下邊緣
 *       4. 上下邊緣兩兩對比,將相似度超過預(yù)設(shè)閾值的碎片執(zhí)行拼接操作,得到原圖
*/

int n = 0;  //左右拼接時需要的迭代器
int m = 0;  //上下拼接時需要的迭代器

//讀取碎片
vector<Mat> fragments_Imread(string files_name);
vector<Mat> fragments_LR_Imread(string files_name);     //讀取左右拼接好的碎片

//保存每張碎片的左右邊緣
vector <vector<Mat>> edge_resection_LR(const vector <Mat>& fragments);

//直方圖對比
bool compare_by_hist(const Mat& img1, const Mat& img2);

//左右拼接
void picture_stitching_LR(const Mat& img1, const Mat& img2);

//對每張碎片的左右邊緣相互對比拼接
void alignment_and_splicing_LR(const vector <Mat>& fragments, const vector<vector<Mat>>& resection_LR);//參數(shù):碎片;碎片的左右邊緣

//保存每張碎片的上下邊緣
vector <vector<Mat>> edge_resection_TB(const vector <Mat>& fragments_LR);

//上下拼接
void picture_stitching_TB(const Mat& img1, const Mat& img2);

//對左右拼接好的碎片進(jìn)行上下對比拼接
void alignment_and_splicing_TB(const vector <Mat>& fragments_LR, const vector<vector<Mat>>& resection_TB);


int main() {
    vector<Mat> fragments = fragments_Imread("res/fragments/");              	//讀取碎片

    vector<vector<Mat> > resection_LR = edge_resection_LR(fragments);           //保存每張碎片的左右邊緣

    alignment_and_splicing_LR(fragments,resection_LR);                          //對每張碎片的左右邊緣相互對比拼接

    vector<Mat> fragments_LR = fragments_LR_Imread("res/fragments_LR/");     	//讀取左右拼接好的碎片

    vector<vector<Mat>> resection_TB = edge_resection_TB(fragments_LR);         //保存拼接好的左右碎片的上下邊緣

    alignment_and_splicing_TB(fragments_LR, resection_TB);                      //對左右拼接好的碎片的上下邊緣相互對比拼接

    Mat result = imread("res/result/0.jpg");
    imshow("Restoration map",result);                                           //展示結(jié)果

    waitKey(0);
    return 0;
}

//讀取碎片
vector<Mat> fragments_Imread(string files_name){
    vector<string> files;
    glob(std::move(files_name),files);
    vector<Mat> fragments;
    for(auto &file : files){
        fragments.push_back(imread(file));
    }
    return fragments;
}
vector<Mat> fragments_LR_Imread(string files_name){
    vector<string> files;
    glob(std::move(files_name),files);
    vector<Mat> fragments_LR;
    for(auto &file : files){
        fragments_LR.push_back(imread(file));
    }
    return fragments_LR;
}

//保存每張碎片的左右邊緣
vector<vector<Mat> > edge_resection_LR(const vector <Mat>& fragments){
    vector<vector<Mat> > resection_LR(fragments.size(), vector<Mat>(2));
    for(int i = 0; i<fragments.size(); i++){
        for(int j = 0; j<2; j++){
            switch (j){
                case 0:     //第 i 張碎片的 左邊;  頂點:(0,0)  尺寸:(10 * 第i張碎片的高/行)
                    resection_LR.at(i).at(j) = fragments.at(i)(Rect(0,0,10, fragments.at(i).rows));
                    break;
                case 1:     //第 i 張碎片的 右邊;  頂點:(第 i 張碎片的寬/列-10,0)  尺寸:(10 * 第i張碎片的高/行)
                    resection_LR.at(i).at(j) = fragments.at(i)(Rect(fragments.at(i).cols-10,0,10, fragments.at(i).rows));
                default:
                    break;
            }
        }
    }
    return resection_LR;
}

//直方圖對比
bool compare_by_hist(const Mat& img1, const Mat& img2){
    Mat tmpImg,orgImg;
    resize(img1, tmpImg, Size(img1.cols, img1.rows));
    resize(img2, orgImg, Size(img2.cols, img2.rows));
    //HSV顏色特征模型(色調(diào)H,飽和度S,亮度V)
    cvtColor(tmpImg, tmpImg, COLOR_BGR2HSV);
    cvtColor(orgImg, orgImg, COLOR_BGR2HSV);
    //直方圖尺寸設(shè)置
    //一個灰度值可以設(shè)定一個bins,256個灰度值就可以設(shè)定256個bins
    //對應(yīng)HSV格式,構(gòu)建二維直方圖
    //每個維度的直方圖灰度值劃分為256塊進(jìn)行統(tǒng)計,也可以使用其他值
    int hBins = 256, sBins = 256;
    int histSize[] = { hBins,sBins };
    //H:0~180, S:0~255,V:0~255
    //H色調(diào)取值范圍
    float hRanges[] = { 0, 180 };
    //S飽和度取值范圍
    float sRanges[] = { 0,255 };
    const float* ranges[] = { hRanges, sRanges };
    int channels[] = { 0,1 };					//二維直方圖
    MatND hist1, hist2;
    calcHist(&tmpImg, 1, channels, Mat(), hist1,2,histSize, ranges, true, false);
    normalize(hist1, hist1, 0, 1, NORM_MINMAX, -1, Mat());
    calcHist(&orgImg, 1, channels, Mat(), hist2, 2, histSize, ranges, true, false);
    normalize(hist2, hist2, 0, 1, NORM_MINMAX, -1, Mat());
    double similarityValue = compareHist(hist1, hist2, CV_COMP_CORREL);
//    cout << "相似度:" << similarityValue << endl;
    return similarityValue >= 0.95;
}

//左右拼接
void picture_stitching_LR(const Mat& img1, const Mat& img2){
    Mat result;
    hconcat(img1,img2,result);
    imwrite("res/fragments_LR/"+to_string(n)+".jpg", result);
    n++;
}

//對每張碎片的左右邊緣相互對比拼接
void alignment_and_splicing_LR(const vector <Mat>& fragments, const vector<vector<Mat>>& resection_LR){
    for(int i = 0; i<fragments.size()-1; i++){            //第 i 張碎片
        for(int j = 0; j<2; j++){                       //第 i 張碎片的第 j 條邊
            for(int k = i; k<fragments.size()-1; k++){    //第 i 張碎片的第 j 條邊 與 第 i 張以后碎片的左右邊緣對比
                for(int l = 0; l<2; l++){
                    if(compare_by_hist(resection_LR.at(i).at(j),resection_LR.at(k+1).at(l))){
                        if(j>l){            //當(dāng)j>l時被對比的邊緣應(yīng)該在對比右邊
                            picture_stitching_LR(fragments.at(i),fragments.at(k+1));
                        } else if(j<l){     //當(dāng)j<l時被對比的邊緣應(yīng)該在對比右邊
                            picture_stitching_LR(fragments.at(k+1),fragments.at(i));
                        }
                    }
                }
            }
        }
    }
}

//上下拼接
void picture_stitching_TB(const Mat& img1, const Mat& img2){
    Mat result;
    vconcat(img1,img2,result);
    imwrite("res/result/"+to_string(m)+".jpg", result);
    m++;
}

//保存左右拼接好的碎片的上下邊緣
vector <vector<Mat>> edge_resection_TB(const vector <Mat>& fragments_LR){
    vector <vector<Mat>> resection_TB(fragments_LR.size(), vector<Mat>(2));
    for(int i = 0; i<fragments_LR.size(); i++){
        for(int j = 0; j<2; j++){
            switch (j){
                case 0:     //第 i 張碎片的 上邊緣;  頂點:(0,0)  尺寸:(第i張碎片的寬/列 * 10)
                    resection_TB.at(i).at(j) = fragments_LR.at(i)(Rect(0,0,fragments_LR.at(i).cols, 10));
                    break;
                case 1:     //第 i 張碎片的 下邊緣;  頂點:(0,第 i 張碎片的高/行-10)  尺寸:(第i張碎片的寬/列 * 10)
                    resection_TB.at(i).at(j) = fragments_LR.at(i)(Rect(0,fragments_LR.at(i).rows-10, fragments_LR.at(i).cols, 10));
                default:
                    break;
            }
        }
    }
    return resection_TB;
}

//對左右拼接好的碎片進(jìn)行上下對比拼接
void alignment_and_splicing_TB(const vector <Mat>& fragments_LR, const vector<vector<Mat>>& resection_TB){
    for(int i = 0; i<fragments_LR.size()-1; i++){               //第 i 張碎片
        for(int j = 0; j<2; j++){                               //第 i 張碎片的第 j 條邊
            for(int k = i; k<fragments_LR.size()-1; k++){       //第 i 張碎片的第 j 條邊 與 第 i 張以后碎片的左右邊緣對比
                for(int l = 0; l<2; l++){
                    if(compare_by_hist(resection_TB.at(i).at(j),resection_TB.at(k+1).at(l))){
//                        picture_stitching_TB(fragments_LR.at(i),fragments_LR.at(k+1));
                        if(j>l){            //當(dāng)j>l時被對比的邊緣應(yīng)該在對比下邊
                            picture_stitching_TB(fragments_LR.at(i),fragments_LR.at(k+1));
                        } else if(j<l){     //當(dāng)j<l時被對比的邊緣應(yīng)該在對比上邊
                            picture_stitching_TB(fragments_LR.at(k+1),fragments_LR.at(i));
                        }
                    }
                }
            }
        }
    }
}

結(jié)果演示

碎片:

拼接結(jié)果:

到此這篇關(guān)于OpenCV實現(xiàn)亂序碎片復(fù)原的文章就介紹到這了,更多相關(guān)OpenCV碎片復(fù)原內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++實現(xiàn)LeetCode(44.外卡匹配)

    C++實現(xiàn)LeetCode(44.外卡匹配)

    這篇文章主要介紹了C++實現(xiàn)LeetCode(44.外卡匹配),本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • Qt實現(xiàn)簡單五子棋小游戲

    Qt實現(xiàn)簡單五子棋小游戲

    這篇文章主要為大家詳細(xì)介紹了Qt實現(xiàn)簡單五子棋小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-08-08
  • C++順序容器(vector、deque、list)的使用詳解

    C++順序容器(vector、deque、list)的使用詳解

    本文主要介紹了C++順序容器(vector、deque、list)的使用詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-06-06
  • C++實現(xiàn)LeetCode(22.生成括號)

    C++實現(xiàn)LeetCode(22.生成括號)

    這篇文章主要介紹了C++實現(xiàn)LeetCode(22.生成括號),本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • C語言 常量,變量及數(shù)據(jù)詳細(xì)介紹

    C語言 常量,變量及數(shù)據(jù)詳細(xì)介紹

    這篇文章主要介紹了C語言 常量,變量及數(shù)據(jù)詳解的相關(guān)資料,需要的朋友可以參考下
    2016-10-10
  • c++連接mysql數(shù)據(jù)庫的兩種方法(ADO連接和mysql api連接)

    c++連接mysql數(shù)據(jù)庫的兩種方法(ADO連接和mysql api連接)

    現(xiàn)在正做一個接口,通過不同的連接字符串操作不同的數(shù)據(jù)庫。要用到mysql數(shù)據(jù)庫,C++連接mysql有2種方法:利用ADO連接、利用mysql自己的api函數(shù)進(jìn)行連接,下面看看如何用吧
    2013-12-12
  • 深入C++浮點數(shù)無效值定義與判定的解決辦法

    深入C++浮點數(shù)無效值定義與判定的解決辦法

    本篇文章是對C++中浮點數(shù)無效值定義與判定進(jìn)行了介紹,需要的朋友參考下
    2013-05-05
  • 在Visual Studio Code中配置C++編譯環(huán)境的問題

    在Visual Studio Code中配置C++編譯環(huán)境的問題

    關(guān)于Visual Studio Code對C++環(huán)境的配置方法應(yīng)該有好多種,我這里用到了其中的兩種,具體內(nèi)容詳情文中給大家詳細(xì)介紹,對Visual Studio Code配置C++編譯環(huán)境相關(guān)知識感興趣的朋友一起看看吧
    2021-07-07
  • C++ Explicit關(guān)鍵字詳細(xì)解析

    C++ Explicit關(guān)鍵字詳細(xì)解析

    以下是對C++中Explicit關(guān)鍵字的用法進(jìn)行了詳細(xì)的介紹,需要的朋友可以過來參考下,希望對大家有所幫助
    2013-09-09
  • C++實現(xiàn)轉(zhuǎn)置矩陣的循環(huán)

    C++實現(xiàn)轉(zhuǎn)置矩陣的循環(huán)

    大家好,本篇文章主要講的是C++實現(xiàn)轉(zhuǎn)置矩陣的循環(huán),感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽
    2022-01-01

最新評論