自写sobel时间比较

11 篇文章 0 订阅
8 篇文章 0 订阅

说明

自己尝试写了一些片段,时间测试如下,以便待查。
居然和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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值