说明
自己尝试写了一些片段,时间测试如下,以便待查。
居然和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