作者PHANTOMAN (源)
看板C_Sharp
标题[心得] 比较阵列的相减後取绝对值速度
时间Fri Jan 15 23:19:41 2010
这份文章起因是因为目前遇到影像处理的小问题,CCD可以每秒抓6张(2452*2054*16),
但是自己写的影像处理的时间需要280ms,也就是每秒只能处理3.5张影像,跟不上影像进
来的速度。第一种解决方案是使用市面上的影像处理软体(ex. Matlab, LabView Vison,
OpenCV),第二种是想办法改进演算法。在经过方案一的交叉测试後後,我开始着手方案
二。
这边简单的说明一下我所使用的CCD运作模式,ActiveX元件将影像放入CCD宣告的显示
记忆体,这时可呼叫ActiveX方法将影像复制一份到我所想要的记忆体,可以是一维,也
可以是二维,但是阵列内的元素数量相同。我想要达成的目标是即时的影像相减(第n张与
第1张相减取绝对值然後以PictureBox显示),为了简化问题,本次文章直接以乱数产生阵
列代表取入的影像,并将重点放在加快阵列相减後取绝对值的速度。
我所使用的硬体为C2D E6550 2.34G*2 RAM 3.25G,,30次测试平均值如下:
Visual Studio 2008 C# 的测试结果
两组一维阵列(1,2452*2054)相减取绝对值,所需时间为52.604ms
两组二维阵列(2452,2054)相减取绝对值,所需时间为278.125ms
Matlab2009b 的测试结果
两组一维阵列(1,2452*2054)相减取绝对值,所需时间为42.819ms
两组二维阵列(2452,2054)相减取绝对值,所需时间为41.405ms
NI Measurement Studio 8.6 的测试结果(使用axCWArray元件)
两组一维阵列(1,2452*2054)相减取绝对值,所需时间为559.375ms
两组二维阵列(2452,2054)相减取绝对值,所需时间为1443.75ms
Maltlab影像处理测试结果
imabsdiff所需时间为86.724ms (两张相减後取绝对值)
imsubstract所需时间为17.726ms (两张影像相减)
Visual Studio 2008 C# 将一维阵列转成影像输出给PictureBox所需时间为31.250ms
小结论:
1. 在C#中使用一维阵列做影像处理能够大幅度的减少运算时间。
2. 两组一维阵列相减後取绝对值,转成影像输出给PictureBox总共需要时间83.854ms
,小赢Matlab(86.724ms) XDD。
3. 若要再加快处理速度,需要考虑多执行绪与组合语言搭配使用。
小问题:
1. 承小结论3,请版上强者大大能够指点我的程式码,提供改进的建议,谢谢。
附上我的程式码
// 比较相同element数量的一维阵列与二维阵列相减时间
// 一维阵列相减52.08ms 、二维阵列相减285.9375ms
// 同回圈内头尾同时计算对时间没有影响
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace myImageSub
{
public partial class mainForm : Form
{
public mainForm()
{
InitializeComponent();
ushort[] myArray1 = new ushort[2452 * 2054];
ushort[] myArray2 = new ushort[2452 * 2054];
ushort[] myArray3 = new ushort[2452 * 2054];
ushort[,] myArray4 = new ushort[2452, 2054];
ushort[,] myArray5 = new ushort[2452, 2054];
ushort[,] myArray6 = new ushort[2452, 2054];
Random myRnd = new Random();
double tempTime01, tempTime02;
TimeSpan clock01 = new TimeSpan();
int cycleTimes = 5;
// 一维阵列计算速度
for (int i = 0; i < cycleTimes; i++)
{
for (int j = 0; j < myArray1.Length; j++)
{
myArray1[j] = (ushort)myRnd.NextDouble();
myArray2[j] = (ushort)myRnd.NextDouble();
}
System.DateTime startTime = DateTime.Now;
for (int j = 0; j < myArray1.Length; j++)
{
myArray3[j] = (ushort)Math.Abs(myArray1[j] - myArray2[j]);
}
clock01 = (DateTime.Now - startTime) + clock01;
}
tempTime01 = (clock01.TotalMilliseconds / cycleTimes);
// 二维阵列计算速度
for (int i = 0; i < cycleTimes; i++)
{
for (int j = 0; j < myArray4.GetLength(1); j++)
{
for (int k = 0; k < myArray4.GetLength(0); k++)
{
myArray4[k, j] = (ushort)myRnd.NextDouble();
myArray5[k, j] = (ushort)myRnd.NextDouble();
}
}
System.DateTime startTime = DateTime.Now;
for (int j = 0; j < myArray4.GetLength(1); j++)
{
for (int k = 0; k < myArray4.GetLength(0); k++)
{
myArray6[k, j] = (ushort)Math.Abs(myArray4[k, j] -
myArray5[k, j]);
}
}
clock01 = (DateTime.Now - startTime) + clock01;
}
tempTime02 = (clock01.TotalMilliseconds / cycleTimes);
MessageBox.Show("一维阵列相减所需时间为" + tempTime01.ToString()
+ " ms \r\n" +
"二维阵列相减所需时间为" + tempTime02.ToString() + " ms");
}
}
}
--
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 140.112.46.87
1F:→ tomnelson:你写得很好,不过这种结论似乎不用经过你验证,稍有程度的 01/16 11:29
2F:→ tomnelson:人早就知道了. 01/16 11:29
3F:→ tomnelson:如果你把上面的程式加上组语版本的比较发表到ASM板,我会 01/16 11:30
4F:→ tomnelson:给个"推"! 01/16 11:31
5F:→ Lucemia:一维比二维快是应该的,因为少了array到记忆体的加法 01/16 13:55
6F:→ Lucemia:要比应该要用unsafe mode用pointer 01/16 13:55
7F:推 andyjy12:为什麽会比Matlab之流的还慢?该不会在debug mode吧? 01/17 20:13
8F:→ bdvstg:推要用unsafe mode的指标来跑 01/18 14:33
9F:→ bdvstg:Matlab矩阵运算是强项 慢是慢在他是直译式的执行 01/18 14:34
10F:→ bdvstg:要快还可以用显卡加速 关键字:CUDA 或 GPU Programming 01/18 14:36