自写sobel时间比较

来源:互联网 发布:c语言下调用opencv 编辑:程序博客网 时间:2024/05/04 05:51

说明

自己尝试写了一些片段,时间测试如下,以便待查。
居然和opencv时间差不多,伤心。

测试条件

win10,i5-6400@2.7GHz,8GB@2400MHz;
opencv2.4.9,VS2010;
图片尺寸3104*4192;
测时方法:clock()
只测量以下程序段,release测10次求均值.

1.最简略版-38ms

核大小为3,四周都没处理,如果要用Isobelx,应注意for循环下标2~w-2;

            uchar *pScanLine1 = Isrc.data;            uchar *pScanLine2 = pScanLine1 + step;            uchar *pScanLine3 = pScanLine2 + step;            uchar *pSobelx = Isobelx.data + step;            for (int i = 1; i < h - 1; i++)            {                for (int j = 1; j < w - 1; j++)                {                    int t = j - 1;                    int t2 = j + 1;                    //计算x方向的sobel值                    int temp = abs(pScanLine1[t2] - pScanLine1[t] \                        + 2 * pScanLine2[t2] - 2 * pScanLine2[t]  \                        + pScanLine3[t2] - pScanLine3[t]);                    pSobelx[j] = temp > 255 ? 255 : temp; //防止溢出                }                pScanLine1 += step;                pScanLine2 += step;                pScanLine3 += step;                pSobelx += step;            }

2.处理下四周-40.5ms

将四周都处理完,可以放心的食用啦。

            uchar *pScanLine1 = Isrc.data;            uchar *pScanLine2 = pScanLine1 + step;            uchar *pScanLine3 = pScanLine2 + step;            uchar *pSobelx = Isobelx.data + step;            for (int i = 1; i < h - 1; i++)            {                for (int j = 1; j < w - 1; j++)                {                    int t = j - 1;                    int t2 = j + 1;                    //计算x方向的sobel值                    int temp = abs(pScanLine1[t2] - pScanLine1[t] \                        + 2 * pScanLine2[t2] - 2 * pScanLine2[t]  \                        + pScanLine3[t2] - pScanLine3[t]);                    pSobelx[j] = temp > 255 ? 255 : temp; //防止溢出                }                pSobelx[0] = pSobelx[1];            //处理每行第一个元素                pSobelx[w - 1] = pSobelx[w - 2];    //处理每行最后一个元素                pScanLine1 += step;                pScanLine2 += step;                pScanLine3 += step;                pSobelx += step;            }            uchar *pSobelx2 = Isobelx.data;            for (int i = 1; i < w - 1; i++)            {                int temp = pSobelx[i + 1] - pSobelx[i - 1];     //处理最后一行元素                pSobelx[i] = temp > 255 ? 255 : temp;                temp = pSobelx2[i + 1] - pSobelx2[i - 1];//处理第一行元素                pSobelx2[i] = temp > 255 ? 255 : temp;            }            //处理四个角点            pSobelx[0] = pSobelx[1];                        pSobelx[w - 1] = pSobelx[w - 2];            pSobelx2[0] = pSobelx2[1];            pSobelx2[w - 1] = pSobelx2[w - 2];

3.简略sobelx+sobely-55.1ms

在同一个循环里完成x和y方向的梯度计算,没有处理四周,谨慎食用。

            uchar *pScanLine1 = Isrc.data;            uchar *pScanLine2 = pScanLine1 + step;            uchar *pScanLine3 = pScanLine2 + step;            uchar *pSobelx = Isobelx.data+step;            uchar *pSobely = Isobely.data+step;            for (int i = 1; i < h - 1; i++)            {                for (int j = 1; j < w - 1; j++)                {                    int t = j - 1;                    int t2 = j + 1;                    //计算x方向的sobel值                    int temp = abs(pScanLine1[t2] - pScanLine1[t] \                        + 2 * pScanLine2[t2] - 2 * pScanLine2[t]  \                        + pScanLine3[t2] - pScanLine3[t]);                    pSobelx[j] = temp > 255 ? 255 : temp; //防止溢出                    //计算y方向的sobel值                    temp = abs(pScanLine3[t] + 2 * pScanLine3[j] \                        + pScanLine3[t2] - pScanLine1[t]  \                        - 2 * pScanLine1[j] - pScanLine1[t2]);                    pSobely[j] = temp > 255 ? 255 : temp;                }                pScanLine1 += step;                pScanLine2 += step;                pScanLine3 += step;                pSobelx += step;                pSobely += step;            }

4.

Appendix 1. 完整主程序

#include<iostream>#include<iomanip>#include<opencv2/opencv.hpp>#include<time.h>#include<stdio.h>#include<string>using namespace std;using namespace cv;int main(int argc, char *argv[]){    const char* dirpath = "E:\\实验记录\\20160511\\1\\";    //const char* dirpath = "E:\\pic\\20150923\\";    string  txtpath = dirpath;    txtpath.append("list.txt");    int picnum = 1;    double timecount = 0;    int locate_timecount = 0;    int locate_maxtime = 0;    int decode_timecount = 0;    int decode_maxtime = 0;    int correctnum = 0;    vector<string> vPicErrName; //store pic name which decoded error    char picname[50] = { 0 };    FILE * fp;    fopen_s(&fp, txtpath.c_str(), "r");    if (fp)    {        while (!feof(fp))        {            fscanf(fp, "%s\r", picname);            string picpath = dirpath;            picpath.append(picname);            //picpath.append("104303192.bmp");            cout << setw(3) << picnum << ":" << picpath << endl;            Mat Isrc = imread(picpath, 0);            //Mat Isrc = imread("103130788.bmp",0);            int h = Isrc.rows;            int w = Isrc.cols;            int step = Isrc.step;            Mat IsrcShowSnap;            Mat Isobelx = Isrc.clone();            Mat Isobely = Isrc.clone();            resize(Isrc, IsrcShowSnap, Size(MIN(320,h),MIN(240,w)));            imshow("Isrc_snap", IsrcShowSnap);            waitKey(10);            time_t tic, toc, tic_s ,tbc;            tic_s = clock();            tic = clock();            uchar *pScanLine1 = Isrc.data;            uchar *pScanLine2 = pScanLine1 + step;            uchar *pScanLine3 = pScanLine2 + step;            uchar *pSobelx = Isobelx.data+step;            uchar *pSobely = Isobely.data+step;            for (int i = 1; i < h - 1; i++)            {                for (int j = 1; j < w - 1; j++)                {                    int t = j - 1;                    int t2 = j + 1;                    //计算x方向的sobel值                    int temp = abs(pScanLine1[t2] - pScanLine1[t] \                        + 2 * pScanLine2[t2] - 2 * pScanLine2[t]  \                        + pScanLine3[t2] - pScanLine3[t]);                    pSobelx[j] = temp > 255 ? 255 : temp; //防止溢出                    //计算y方向的sobel值                    temp = abs(pScanLine3[t] + 2 * pScanLine3[j] \                        + pScanLine3[t2] - pScanLine1[t]  \                        - 2 * pScanLine1[j] - pScanLine1[t2]);                    pSobely[j] = temp > 255 ? 255 : temp;                }                pScanLine1 += step;                pScanLine2 += step;                pScanLine3 += step;                pSobelx += step;                pSobely += step;            }            toc = clock();            tbc = toc - tic;            timecount += tbc;            cout << "SobelX:" << tbc << "ms" << endl;//#ifdef _DEBUG            imshow("Isobelx", Isobelx);            char c = 0;            c = waitKey();//#endif                        if (c == 13)    //回车结束            {                cout << "Mean Time:" <<timecount/picnum << "ms" << endl;                break;            }            picnum++;        }    }    else    {        cout << "Error:File open error!";    }            return 0;}

Appendix 2.图片列表脚本

/b就是纯文件名,/on是按名称排列,>是重定向,>>是追加到文本里。

@echo off dir /b /on *.bmp >list.txt
0 0
原创粉丝点击