欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++ OpenCV實(shí)現(xiàn)抖音"藍(lán)線挑戰(zhàn)"特效

 更新時(shí)間:2022年01月17日 08:41:32   作者:Zero___Chen  
這篇文章主要介紹了如何使用OpenCV C++ 實(shí)現(xiàn)抖音上的特效“藍(lán)線挑戰(zhàn)”。文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)OpenCV有一定的幫助,需要的可以參考一下

前言

本文將使用OpenCV C++ 實(shí)現(xiàn)抖音上的特效“藍(lán)線挑戰(zhàn)”。雖然看起來(lái)覺(jué)得很牛的樣子,但如果了解其中的原理就非常簡(jiǎn)單了。本案例是我自己對(duì)于這個(gè)特效實(shí)現(xiàn)過(guò)程的理解,僅供參考。

算法原理可以分為三個(gè)流程:

1、將視頻(圖像)從(頂->底)或(左->右)逐行(列)掃描圖像。

2、將掃描完成的行(列)像素重新生成定格圖像。

3、使用原幀圖像像素填充未掃描到的像素。

接下來(lái)就具體來(lái)看看是如何實(shí)現(xiàn)的吧。

一、圖像掃描

首先第一步,拿到一個(gè)視頻(很多幀圖像)可以簡(jiǎn)單的看成圖像處理。我們需要將圖像從頂?shù)降字鹦羞M(jìn)行像素掃描,當(dāng)然也可以從左到右逐列掃描,這要看你想要實(shí)現(xiàn)什么樣的效果。在這里,我實(shí)現(xiàn)的是從上到下逐行掃描。效果如圖所示。

二、生成定格圖像

所謂生成定格圖像就是將我們每掃描到的行像素重新進(jìn)行繪制。

    //從頂向下逐行掃描圖像
    if (h < height)
    {
        h++;
        //將掃描到的圖像像素進(jìn)行重新繪制,生成新圖像
        for (int j = 0; j < width; j++)
        {
            for (int c = 0; c < 3; c++)
            {
                temp.at<Vec3b>(h, j)[c] = canvas.at<Vec3b>(h, j)[c];
            }
        }
        //繪制掃描過(guò)程
        line(canvas, Point(0, h), Point(width, h), Scalar(255, 255, 0), 2);
    }

如圖所示,這是使用上面代碼段實(shí)現(xiàn)的逐行掃描生成定格圖像。從效果上看,已經(jīng)得到了我們想要的大致效果了。不過(guò)現(xiàn)在的問(wèn)題是,經(jīng)掃描到的行有像素填充,未掃描到的行還是漆黑一片。所以接下來(lái)我們需要做的就是將未掃描到的行用原圖進(jìn)行填充。具體請(qǐng)看源碼注釋。

三、圖像混合

//將兩幅圖像進(jìn)行線性混合
bool Linear_Blend(Mat src1, Mat src2, Mat& dst)
{
?? ?/*
?? ?參數(shù)說(shuō)明:
?? ?src1:生成的定格圖像。由于生成的定格圖像是從頂往下逐行掃描,故在掃描線下的像素為0
?? ?src2:原視頻幀圖像
?? ?dst:新生成的定格圖像。
?? ?算法原理:經(jīng)掃描到的像素用src1進(jìn)行填充,未掃描到的像素用src2進(jìn)行填充,這樣就可以得到我們所要的效果了。
?? ?*/

?? ?for (int i = 0; i < src1.rows; i++)
?? ?{
?? ??? ?for (int j = 0; j < src1.cols; j++)
?? ??? ?{
?? ??? ??? ?for (int c = 0; c < 3; c++)
?? ??? ??? ?{
?? ??? ??? ??? ?if (src1.at<Vec3b>(i, j)[0] != 0)
?? ??? ??? ??? ?{
?? ??? ??? ??? ??? ?dst.at<Vec3b>(i, j)[c] = src1.at<Vec3b>(i, j)[c];
?? ??? ??? ??? ?}
?? ??? ??? ??? ?else
?? ??? ??? ??? ?{
?? ??? ??? ??? ??? ?dst.at<Vec3b>(i, j)[c] = src2.at<Vec3b>(i, j)[c];
?? ??? ??? ??? ?}
?? ??? ??? ?}
?? ??? ?}
?? ?}

?? ?return true;
}

四、效果顯示

如上圖所示,至此我們已經(jīng)完成了案例所想要的效果。請(qǐng)參考源碼,注釋也比較詳細(xì)了。

五、源碼

#include<iostream>
#include<opencv2/opencv.hpp>
using namespace std;
using namespace cv;

/*
抖音特效:藍(lán)線挑戰(zhàn)
算法原理:
?? ?1、將視頻(圖像)從(頂->底)或(左->右)逐行(列)掃描圖像。
?? ?2、將掃描完成的行(列)像素重新生成定格圖像
?? ?3、使用原幀圖像像素填充未掃描到的像素
*/

//將兩幅圖像進(jìn)行線性混合
bool Linear_Blend(Mat src1, Mat src2, Mat& dst)
{
?? ?/*
?? ?參數(shù)說(shuō)明:
?? ?src1:生成的定格圖像。由于生成的定格圖像是從頂往下逐行掃描,故在掃描線下的像素為0
?? ?src2:原視頻幀圖像
?? ?dst:新生成的定格圖像。
?? ?算法原理:經(jīng)掃描到的像素用src1進(jìn)行填充,未掃描到的像素用src2進(jìn)行填充,這樣就可以得到我們所要的效果了。
?? ?*/

?? ?for (int i = 0; i < src1.rows; i++)
?? ?{
?? ??? ?for (int j = 0; j < src1.cols; j++)
?? ??? ?{
?? ??? ??? ?for (int c = 0; c < 3; c++)
?? ??? ??? ?{
?? ??? ??? ??? ?if (src1.at<Vec3b>(i, j)[0] != 0)
?? ??? ??? ??? ?{
?? ??? ??? ??? ??? ?dst.at<Vec3b>(i, j)[c] = src1.at<Vec3b>(i, j)[c];
?? ??? ??? ??? ?}
?? ??? ??? ??? ?else
?? ??? ??? ??? ?{
?? ??? ??? ??? ??? ?dst.at<Vec3b>(i, j)[c] = src2.at<Vec3b>(i, j)[c];
?? ??? ??? ??? ?}
?? ??? ??? ?}
?? ??? ?}
?? ?}

?? ?return true;
}

int main()
{
?? ?VideoCapture capture;
?? ?capture.open("test.avi");
?? ?if (!capture.isOpened())
?? ?{
?? ??? ?cout << "can not open the camera!" << endl;
?? ??? ?system("pause");
?? ??? ?return -1;
?? ?}

?? ?int width = capture.get(CAP_PROP_FRAME_WIDTH);//視頻幀寬
?? ?int height = capture.get(CAP_PROP_FRAME_HEIGHT);//視頻幀高

?? ?//保存視頻
?? ?VideoWriter writer;
?? ?int fourcc = writer.fourcc('m', 'p', '4', 'v'); //視頻編碼
?? ?Size size(capture.get(CAP_PROP_FRAME_WIDTH), capture.get(CAP_PROP_FRAME_HEIGHT));
?? ?writer.open("result.avi", fourcc, 30, size, true);

?? ?int h = 0;//定義變量,代表當(dāng)前掃描高度

?? ?//用于生成定格照
?? ?Mat temp = Mat::zeros(Size(width, height), CV_8UC3);
?? ?
?? ?Mat frame;
?? ?while (capture.read(frame))
?? ?{
?? ??? ?//將圖像拷貝一份,用于每幀更新
?? ??? ?Mat canvas = frame.clone();

?? ??? ?//從頂向下逐行掃描圖像
?? ??? ?if (h < height)
?? ??? ?{
?? ??? ??? ?h++;
?? ??? ??? ?//將掃描到的圖像像素進(jìn)行重新繪制,生成新圖像
?? ??? ??? ?for (int j = 0; j < width; j++)
?? ??? ??? ?{
?? ??? ??? ??? ?for (int c = 0; c < 3; c++)
?? ??? ??? ??? ?{
?? ??? ??? ??? ??? ?temp.at<Vec3b>(h, j)[c] = canvas.at<Vec3b>(h, j)[c];
?? ??? ??? ??? ?}
?? ??? ??? ?}
?? ??? ??? ?//繪制掃描過(guò)程
?? ??? ??? ?line(canvas, Point(0, h), Point(width, h), Scalar(255, 255, 0), 2);
?? ??? ?}

?? ??? ?Mat result = Mat::zeros(frame.size(), frame.type());//藍(lán)線挑戰(zhàn)最終定格圖
?? ??? ?Linear_Blend(temp, canvas, result); //將兩張圖像進(jìn)行像素疊加

?? ??? ?//writer.write(temp);//進(jìn)行視頻保存

?? ??? ?imshow("定格圖像", temp);
?? ??? ?imshow("原視頻幀", canvas);
?? ??? ?imshow("藍(lán)線挑戰(zhàn)", result);

?? ??? ?char key = waitKey(10);
?? ??? ?if (key == 27) break;
?? ?}

?? ?capture.release();
?? ?system("pause");
?? ?return 0;
}

總結(jié)

本文使用OpenCV C++ 實(shí)現(xiàn)抖音特效“藍(lán)線挑戰(zhàn)”,關(guān)鍵步驟有以下幾點(diǎn)。

1、將圖像進(jìn)行逐行掃描

2、將掃描到的像素逐行生成定格圖像

3、將定格圖像與原圖像進(jìn)行像素疊加。

以上就是C++ OpenCV實(shí)現(xiàn)抖音"藍(lán)線挑戰(zhàn)"特效的詳細(xì)內(nèi)容,更多關(guān)于C++ OpenCV藍(lán)線挑戰(zhàn)特效的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 自己模擬寫(xiě)C++中的String類型實(shí)例講解

    自己模擬寫(xiě)C++中的String類型實(shí)例講解

    下面小編就為大家?guī)?lái)一篇自己模擬寫(xiě)C++中的String類型實(shí)例講解。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-07-07
  • C語(yǔ)言下快速排序(挖坑法)詳解

    C語(yǔ)言下快速排序(挖坑法)詳解

    大家好,本篇文章主要講的是C語(yǔ)言下快速排序(挖坑法)詳解,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽
    2021-12-12
  • 虛函數(shù)表-C++多態(tài)的實(shí)現(xiàn)原理解析

    虛函數(shù)表-C++多態(tài)的實(shí)現(xiàn)原理解析

    這篇文章主要介紹了虛函數(shù)表-C++多態(tài)的實(shí)現(xiàn)原理,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-02-02
  • 詳解C語(yǔ)言中的字符串?dāng)?shù)組

    詳解C語(yǔ)言中的字符串?dāng)?shù)組

    這篇文章主要介紹了C語(yǔ)言中的字符串?dāng)?shù)組,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-09-09
  • 詳解C語(yǔ)言解決經(jīng)典問(wèn)題之兔子產(chǎn)子

    詳解C語(yǔ)言解決經(jīng)典問(wèn)題之兔子產(chǎn)子

    有一對(duì)兔子,從出生后的第 3 個(gè)月起每個(gè)月都生一對(duì)兔子。小兔子長(zhǎng)到第 3 個(gè)月后每個(gè)月又生一對(duì)兔子,假設(shè)所有的兔子都不死,問(wèn) 30 個(gè)月內(nèi)每個(gè)月的兔子總數(shù)為多少?本文將用C語(yǔ)言解決這一經(jīng)典問(wèn)題,需要的可以參考一下
    2022-03-03
  • 淺談mwArray和一般數(shù)組的區(qū)別

    淺談mwArray和一般數(shù)組的區(qū)別

    下面小編就為大家?guī)?lái)一篇淺談mwArray和一般數(shù)組的區(qū)別。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-12-12
  • C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之單向鏈表詳解分析

    C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之單向鏈表詳解分析

    鏈表可以說(shuō)是一種最為基礎(chǔ)的數(shù)據(jù)結(jié)構(gòu)了,而單向鏈表更是基礎(chǔ)中的基礎(chǔ)。鏈表是由一組元素以特定的順序組合或鏈接在一起的,不同元素之間在邏輯上相鄰,但是在物理上并不一定相鄰。在維護(hù)一組數(shù)據(jù)集合時(shí),就可以使用鏈表,這一點(diǎn)和數(shù)組很相似
    2021-11-11
  • C++11 call_once 和 once_flag的使用與區(qū)別

    C++11 call_once 和 once_flag的使用與區(qū)別

    本文主要介紹了C++11 call_once 和 once_flag的使用與區(qū)別,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • c++ 求數(shù)組最大最小值函數(shù)的實(shí)現(xiàn)

    c++ 求數(shù)組最大最小值函數(shù)的實(shí)現(xiàn)

    這篇文章主要介紹了c++ 求數(shù)組最大最小值函數(shù)的實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • C++實(shí)現(xiàn)順序表的常用操作(插入刪出查找輸出)

    C++實(shí)現(xiàn)順序表的常用操作(插入刪出查找輸出)

    實(shí)現(xiàn)順序表的插入,刪除,查找,輸出操作在C語(yǔ)言中經(jīng)常用到。下面小編給大家整理實(shí)現(xiàn)代碼,一起看下吧
    2016-08-08

最新評(píng)論