1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        使用OpenCV4實(shí)現(xiàn)硬件級別加速

        共 477字,需瀏覽 1分鐘

         ·

        2021-11-27 14:08

        點(diǎn)擊上方小白學(xué)視覺”,選擇加"星標(biāo)"或“置頂

        重磅干貨,第一時(shí)間送達(dá)

        本文使用一個(gè)向量點(diǎn)乘的例子,來展示universal intrinsics的的提速。


        我們有兩個(gè)向量vec1和vec2,將對應(yīng)元素相乘,然后累加起來。計(jì)算公式為:

        sum=vec1[0]*vec2[0] + vec1[1]*vec2[1]+?... +?vec1[n]*vec2[n].


        如果采用純C語言,兩個(gè)行向量的點(diǎn)乘實(shí)現(xiàn)如下(如代碼顯示不完整,可以左右滑動(dòng);或橫屏閱讀)

        1. float dotproduct_c_float(Mat vec1, Mat vec2)

        2. {

        3. float * pV1 = vec1.ptr(0);

        4. float * pV2 = vec2.ptr(0);

        5. float sum = 0.0f;

        6. for (size_t c = 0; c < vec1.cols; c++)

        7. {

        8. sum += pV1[c] * pV2[c];

        9. }

        10. return sum;

        11. }

        如果采用OpenCV的universal intrinsics,兩個(gè)行向量的點(diǎn)乘實(shí)現(xiàn)如下:

        (注意:下面函數(shù)僅為展示原理,未考慮數(shù)組長度不是16(32或64)字節(jié)倍數(shù)情況)

        1. float dotproduct_simd_float(Mat vec1, Mat vec2)

        2. {

        3. float * pV1 = vec1.ptr(0);

        4. float * pV2 = vec2.ptr(0);

        5. size_t step = sizeof(v_float32)/sizeof(float);


        6. //向量元素全部初始化為零

        7. v_float32 v_sum = vx_setzero_f32();

        8. for (size_t c = 0; c < vec1.cols; c+=step)

        9. {

        10. v_float32 v1 = vx_load(pV1+c);

        11. v_float32 v2 = vx_load(pV2+c);

        12. //把乘積累加

        13. v_sum += v1 * v2;

        14. }

        15. //把向量里的所有元素求和

        16. float sum = v_reduce_sum(v_sum);


        17. return sum;

        18. }

        例程使用Open AI Lab的EAIDK-310開發(fā)板,OpenCV4.2.0,CPU型號為是RK3228H,采用ARM四核64位處理器 ,四核Cortex-A53,最高1.3GHz。兩個(gè)例子的編譯命令分別如下(注意:皆采用了-O3選項(xiàng)以提速):


        g++ dotproduct-c.cpp -o dotproduct-c -O3 -I/usr/local/include/opencv4 -lopencv_core
        g++?dotproduct-simd.cpp?-o?dotproduct-simd?-O3?-I/usr/local/include/opencv4?-lopencv_core

        運(yùn)行耗時(shí)如下圖

        從兩個(gè)函數(shù)的耗時(shí)可以看出,采用OpenCV的universal intrinsics后耗時(shí)僅為一半,速度翻倍。


        兩個(gè)例程的完整源代碼如下。首先是C語言版本的dotproduct-c.cpp:

        1. #include


        2. using namespace cv;


        3. float dotproduct_c_float(Mat vec1, Mat vec2)

        4. {

        5. float * pV1 = vec1.ptr(0);

        6. float * pV2 = vec2.ptr(0);

        7. float sum = 0.0f;

        8. for (size_t c = 0; c < vec1.cols; c++)

        9. {

        10. sum += pV1[c] * pV2[c];

        11. }

        12. return sum;

        13. }


        14. int main(int argc, char ** argv)

        15. {


        16. Mat vec1(1, 16*1024*1024, CV_32FC1);

        17. Mat vec2(1, 16*1024*1024, CV_32FC1);


        18. vec1.ptr(0)[2]=3.3f;

        19. vec2.ptr(0)[2]=2.0f;


        20. double t = 0.0;

        21. t = (double)getTickCount();


        22. float sum = dotproduct_c_float(vec1, vec2);


        23. t = ((double)getTickCount() - t) / (double)getTickFrequency() * 1000;

        24. printf("C time = %gms\n", t);

        25. printf("sum=%g\n", sum);


        26. return 0;

        27. }

        dotproduct-simd.cpp如下:

        1. #include

        2. #include

        3. #include

        4. using namespace cv;


        5. float dotproduct_simd_float(Mat vec1, Mat vec2)

        6. {

        7. float * pV1 = vec1.ptr(0);

        8. float * pV2 = vec2.ptr(0);

        9. size_t step = sizeof(v_float32)/sizeof(float);


        10. //向量元素全部初始化為零

        11. v_float32 v_sum = vx_setzero_f32();

        12. for (size_t c = 0; c < vec1.cols; c+=step)

        13. {

        14. v_float32 v1 = vx_load(pV1+c);

        15. v_float32 v2 = vx_load(pV2+c);

        16. //把乘積累加

        17. v_sum += v1 * v2;

        18. }

        19. //把向量里的所有元素求和

        20. float sum = v_reduce_sum(v_sum);


        21. return sum;

        22. }


        23. int main(int argc, char ** argv)

        24. {


        25. Mat vec1(1, 16*1024*1024, CV_32FC1);

        26. Mat vec2(1, 16*1024*1024, CV_32FC1);


        27. vec1.ptr(0)[2]=3.3f;

        28. vec2.ptr(0)[2]=2.0f;


        29. double t = 0.0;

        30. t = (double)getTickCount();


        31. float sum = dotproduct_simd_float(vec1, vec2);


        32. t = ((double)getTickCount() - t) / (double)getTickFrequency() * 1000;

        33. printf("SIMD time = %gms\n", t);


        34. printf("sum=%g\n", sum);


        35. return 0;

        36. }


        下載1:OpenCV-Contrib擴(kuò)展模塊中文版教程
        在「小白學(xué)視覺」公眾號后臺回復(fù):擴(kuò)展模塊中文教程,即可下載全網(wǎng)第一份OpenCV擴(kuò)展模塊教程中文版,涵蓋擴(kuò)展模塊安裝、SFM算法、立體視覺、目標(biāo)跟蹤、生物視覺、超分辨率處理等二十多章內(nèi)容。

        下載2:Python視覺實(shí)戰(zhàn)項(xiàng)目52講
        小白學(xué)視覺公眾號后臺回復(fù):Python視覺實(shí)戰(zhàn)項(xiàng)目,即可下載包括圖像分割、口罩檢測、車道線檢測、車輛計(jì)數(shù)、添加眼線、車牌識別、字符識別、情緒檢測、文本內(nèi)容提取、面部識別等31個(gè)視覺實(shí)戰(zhàn)項(xiàng)目,助力快速學(xué)校計(jì)算機(jī)視覺。

        下載3:OpenCV實(shí)戰(zhàn)項(xiàng)目20講
        小白學(xué)視覺公眾號后臺回復(fù):OpenCV實(shí)戰(zhàn)項(xiàng)目20講即可下載含有20個(gè)基于OpenCV實(shí)現(xiàn)20個(gè)實(shí)戰(zhàn)項(xiàng)目,實(shí)現(xiàn)OpenCV學(xué)習(xí)進(jìn)階。

        交流群


        歡迎加入公眾號讀者群一起和同行交流,目前有SLAM、三維視覺、傳感器、自動(dòng)駕駛、計(jì)算攝影、檢測、分割、識別、醫(yī)學(xué)影像、GAN、算法競賽等微信群(以后會(huì)逐漸細(xì)分),請掃描下面微信號加群,備注:”昵稱+學(xué)校/公司+研究方向“,例如:”張三?+?上海交大?+?視覺SLAM“。請按照格式備注,否則不予通過。添加成功后會(huì)根據(jù)研究方向邀請進(jìn)入相關(guān)微信群。請勿在群內(nèi)發(fā)送廣告,否則會(huì)請出群,謝謝理解~


        瀏覽 41
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評論
        圖片
        表情
        推薦
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            日本一本一道 | 色悠久久综合 | 日韩亚洲一区二区精品成人 | 国产色片| 国产精品久久久久久久久大全 | 青娱乐 - 亚洲高清视频在线观看 亚洲色逼 | 天天久久夜夜一起射 | 乱淫麻麻怀孕小说合集 | 曰韩理论片 | 播操代毛的大逼 |