使用心得1:
c#中可以使用指针数组代替c语言中的二维数组。
使用心得2:
c#中的指针生命周期仅限于为指针赋值的函数体,当函数返回时,指针的行为是不可预料的。
具体代码为:
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing.Imaging;
using System.Drawing;
using System.Runtime.InteropServices;
namespace sand.shilin.ModuleMatching
{
public unsafe class ModuleMatchingFaster
{
public ModuleMatchingFaster()
{
}
public unsafe static int[] MatchingFast()
{
int[] MatchedLocation = new int[2];
Bitmap s = global::sand.shilin.ModuleMatching.Properties.Resources.lena2562;
byte*[] S = new byte*[s.Height];
for (int i = 0; i < s.Height; i++)
{
byte* pt = stackalloc byte[s.Width];
S[i] = pt;
}
Image2Ptr(S, s);
int sums = sum(s, S);
s = global::sand.shilin.ModuleMatching.Properties.Resources.lenaT;
byte*[] T = new byte*[s.Height];
for (int i = 0; i < s.Height; i++)
{
byte* pt = stackalloc byte[s.Width];
T[i] = pt;
}
Image2Ptr(T, s);
int sumT = sum(s, T);
int f = Convert.ToInt32(sumT * 0.1);
int sumWeldingH = sums;
int sumWelding = sums;
int avrSource = sums / (35 * 44);
int avrModule = sumT / (35 * 44);
int*[] D = new int*[221];
for (int i = 0; i < 212; i++)
{
int* pt = stackalloc int[221];
D[i] = pt;
}
for (int i = 0; i < 212; i++)
{
for (int j = 0; j < 221; j++)
{
int wucha = 0;
bool breaks = false;
int k = 0;
while (breaks == false && k < 44)
{
for (int l = 0; l < 35; l+=1)
{
wucha += Math.Abs(*(S[k + i] + l + j) - avrSource - *(T[k] + l) + avrModule);
if (wucha >= f)
{
breaks = true;
break;
}
}
k += 1;
}
int hang = 0;
for (int m = 0; m < 44; m++)
{
hang = hang - *(S[i + m] + j) + *(S[i + m] + j + 35 - 1);
}
sumWelding = sumWelding + hang;
avrSource = sumWelding / (35 * 44);
if (wucha < f)
{
f = wucha;
}
*(D[i] + j) = wucha;
}
int lie = 0;
for (int n = 0; n < 35; n++)
{
lie += *(S[i + 35 - 1] + n) - *(S[i] + n);
}
sumWeldingH = sumWeldingH + lie;
sumWelding = sumWeldingH;
avrSource = sumWeldingH / (35 * 44);
}
int min = *(D[0]);
int p1 = 0;
int p2 = 0;
for (int i = 0; i < 212; i++)
{
for (int j = 0; j < 221; j++)
{
if (*(D[i] + j) < min)
{
min = *(D[i] + j);
p1 = i;
p2 = j;
}
}
}
int mmmm = min;
MatchedLocation[0] = p1;
MatchedLocation[1] = p2;
return MatchedLocation;
}
unsafe private static void Image2Ptr(byte*[] S, Bitmap s)
{
BitmapData sData = s.LockBits(new Rectangle(0, 0, s.Width, s.Height),
ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
int sstride = sData.Stride;
System.IntPtr sScan0 = sData.Scan0;
int sOffset = sstride - s.Width * 3;
byte* sp = (byte*)(void*)sScan0;
for (int i = 0; i < s.Height; i++)
{
for (int j = 0; j < s.Width; j++)
{
*(S[i] + j) = sp[0];
sp += 3;
}
sp += sOffset;
}
s.UnlockBits(sData);
}
unsafe private static int sum(Bitmap s, byte*[] S)
{
int sum = 0;
for (int i = 0; i < 44; i++)
{
for (int j = 0; j < 35; j++)
{
sum += *(S[i] + j);
}
}
return sum;
}
}
}
这是一个成功的代码。
以下是一个不成功的代码。
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
namespace sand.shilin.ModuleMatching
{
[Obsolete]
unsafe public class ModuleMatching
{
Bitmap s = global::sand.shilin.ModuleMatching.Properties.Resources.lena2562;
Bitmap t = global::sand.shilin.ModuleMatching.Properties.Resources.lenaT;
byte*[] ptrSource;
byte*[] ptrModule;
public ModuleMatching()
{
ptrModule = new byte*[t.Height];
for (int i = 0; i < t.Height; i++)
{
byte* pt = stackalloc byte[t.Width];
ptrModule[i] = pt;
}
ptrSource = new byte*[s.Height];
for (int i = 0; i < s.Height; i++)
{
byte* pt = stackalloc byte[s.Width];
ptrSource[i] = pt;
}
CreatePtr(t, ptrModule);
//int[,] MODULE = new int[44, 35];
//for (int i = 0; i < 44; i++)
// for (int j = 0; j < 35; j++)
// MODULE[i, j] = *(ptrModule[i] + j);
}
unsafe public int[] MatchingFast()
{
int[] MatchedLocation = new int[2];
CreatePtr(s, ptrSource);
int sums = sum(ptrSource);
int sumT = sum(ptrModule);
int f = Convert.ToInt32(sumT);
int sumWeldingH = sums;
int sumWelding = sums;
int avrSource = sums / (t.Width * t.Height);
int avrModule = sumT / (t.Width * t.Height);
int*[] D = new int*[s.Height - t.Height];
for (int i = 0; i < s.Height - t.Height; i++)
{
int* pt = stackalloc int[s.Height - t.Height];
D[i] = pt;
}
for (int i = 0; i < s.Height - t.Height; i++)
{
for (int j = 0; j < s.Width - t.Width; j++)
{
int wucha = 0;
bool breaks = false;
int k = 0;
while (breaks == false && k < t.Height)
{
for (int l = 0; l < t.Width; l += 1)
{
wucha += Math.Abs(*(ptrSource[k + i] + l + j) - avrSource - *(ptrModule[k] + l) + avrModule);
if (wucha >= f)
{
breaks = true;
break;
}
}
k += 1;
}
int hang = 0;
for (int m = 0; m < t.Height; m++)
{
hang = hang - *(ptrSource[i + m] + j) + *(ptrSource[i + m] + j + t.Width - 1);
}
sumWelding = sumWelding + hang;
avrSource = sumWelding / (t.Width * t.Height);
if (wucha < f)
{
f = wucha;
}
*(D[i] + j) = wucha;
}
int lie = 0;
for (int n = 0; n < t.Width; n++)
{
lie += *(ptrSource[i + t.Width - 1] + n) - *(ptrSource[i] + n);
}
sumWeldingH = sumWeldingH + lie;
sumWelding = sumWeldingH;
avrSource = sumWeldingH / (t.Width * t.Height);
}
int min = *(D[0]);
int p1 = 0;
int p2 = 0;
for (int i = 0; i < s.Height - t.Height; i++)
{
for (int j = 0; j < s.Width - t.Width; j++)
{
if (*(D[i] + j) < min)
{
min = *(D[i] + j);
p1 = i;
p2 = j;
}
}
}
int mmmm = min;
MatchedLocation[0] = p1;
MatchedLocation[1] = p2;
return MatchedLocation;
}
unsafe private void CreatePtr(Bitmap s, byte*[] p)
{
BitmapData sData = s.LockBits(new Rectangle(0, 0, s.Width, s.Height),
ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
int sstride = sData.Stride;
System.IntPtr sScan0 = sData.Scan0;
int sOffset = sstride - s.Width * 3;
byte* sp = (byte*)(void*)sScan0;
for (int i = 0; i < s.Height; i++)
{
for (int j = 0; j < s.Width; j++)
{
*(p[i] + j) = sp[0];
sp += 3;
}
sp += sOffset;
}
s.UnlockBits(sData);
}
unsafe private int sum(byte*[] p)
{
int sum = 0;
for (int i = 0; i < t.Height; i++)
{
for (int j = 0; j < t.Width; j++)
{
sum += *(p[i] + j);
}
}
return sum;
}
}
}
在构造函数返回后,ptrModule的值变得不可预料,在MatchingFast中,ptrModule已经变得不可用。