I got stuck with Access violation exception in managed code. Histogram pointer is not null and everything seems ok. Got example of creating IntPtr's from http://www.emgu.com/forum/viewtopic.php?f=8&t=59
// initializing data
var random = new Random();
var array = new double[1000];
for (int i = 0; i < 1000; i++)
{
array[i] = random.NextDouble();
}
var arrayPtr = GetDataPtr(array);
//initializing ranges array
double[] rangesArray = { 0, 1 };
var rangesArrayPtr = GetRangesArrayPtr(rangesArray);
//creating and querying histogram
var histogramStructure = CvInvoke.cvCreateHist(1, new[] {20}, HIST_TYPE.CV_HIST_ARRAY, rangesArrayPtr, true);
var histogram = CvInvoke.cvMakeHistHeaderForArray(1, new[] { 20 }, histogramStructure, arrayPtr, rangesArrayPtr, 1);
CvInvoke.cvNormalizeHist(histogram, 1.0);
CvInvoke.cvQueryHistValue_1D(histogram, 0); // getting exception here
help methods
private static IntPtr[] GetRangesArrayPtr(double[] array)
{
var ranges = new IntPtr[1];
ranges[0] = Marshal.AllocHGlobal(array.Length * sizeof(double));
Marshal.Copy(array, 0, ranges[0], array.Length);
return ranges;
}
private static IntPtr GetDataPtr(double[] array)
{
var ranges = new IntPtr();
ranges = Marshal.AllocHGlobal(array.Length * sizeof(double));
Marshal.Copy(array, 0, ranges,array.Length);
return ranges;
}
I had the same problem in a recent project and solved it by copying the histogram values into a new array.
Double[] histtemp = new double[255];
Histogram.MatND.ManagedArray.CopyTo(histtemp,0);
Now you can access the histogram values in histtemp. I hope it will help future viewers.
Related
I was migrating a function from a dll to C# and I found a line of code that I don't understand:
< Module >.lm_minimize(((Vector<CalPoint>)calPoints).Size, n_par1, par, (ILMCallbacks)callbacks, (lm_data_type)data, control);
When I try to enter the class there is code in hexadecimal (I guess it's auto generated code) that I can't copy.
This is the code:
internal static void lm_minimize(
int m_dat,
int n_par,
double[] par,
ILMCallbacks callbacks,
lm_data_type data,
lm_control_type control)
{
double[] numArray = new double[m_dat];
double[] diag = new double[n_par];
double[] qtf = new double[n_par];
double[] fjac = new double[m_dat * n_par];
double[] wa1 = new double[n_par];
double[] wa2 = new double[n_par];
double[] wa3 = new double[n_par];
double[] wa4 = new double[m_dat];
int[] ipvt = new int[n_par];
control.info = 0;
control.nfev = 0;
\u003CModule\u003E.lm_lmdif(m_dat, n_par, par, numArray, control.ftol, control.xtol, control.gtol, control.maxcall * (n_par + 1), control.epsilon, diag, 1, control.stepbound, ref control.info, ref control.nfev, fjac, ipvt, qtf, wa1, wa2, wa3, wa4, callbacks, data);
callbacks.lm_printout(n_par, par, m_dat, numArray, data, -1, 0, control.nfev);
control.fnorm = \u003CModule\u003E.\u003FA0x6d25334e\u002Elm_enorm(m_dat, 0, numArray);
if (control.info >= 0)
return;
control.info = 10;
}
And this code calls the function lm_mdif. Part of the code is like this:
\u003CModule\u003E.\u003FA0x6d25334e\u002E\u003F\u0024S1\u0040\u003F1\u003F\u003Flm_lmdif\u0040\u0040YMXHHP\u002401AN0NNNHN0HNA\u0024CAH10P\u002401AH00000A\u0024AAUILMCallbacks\u0040\u0040P\u0024AAVlm_data_type\u0040\u0040\u0040Z\u0040\u0024\u0024Q4IA |= 1U;
// ISSUE: fault handler
I wanted to know if anyone knows what the LM_MINIMIZE function is for, I can't find what it is for..
Thanks
I tried migrate the library code to C#.
I am working with Unity 4.5, grabbing images as bytes arrays (each byte represent a channel, taking 4 bytes per pixel (rgba) and displaying them on a texture converting the array to a Color32 array, using this loop:
img = new Color32[byteArray.Length / nChannels]; //nChannels being 4
for (int i=0; i< img.Length; i++) {
img[i].r = byteArray[i*nChannels];
img[i].g = byteArray[i*nChannels+1];
img[i].b = byteArray[i*nChannels+2];
img[i].a = byteArray[i*nChannels+3];
}
Then, it is applied to the texture using:
tex.SetPixels32(img);
However, this slows down the application significantly (this loop is executed on every single frame), and I would like to know if there is any other way to speed up the copying process. I've found some people (Fast copy of Color32[] array to byte[] array) using the Marshal.Copy functions in order to do the reverse process (Color32 to byte array), but I have not been able to make it work to copy a byte array to a Color32 array. Does anybody know a faster way?
Thank you in advance!
Yes, Marshal.Copy is the way to go. I've answered a similar question here.
Here's a generic method to copy from struct[] to byte[] and vice versa
private static byte[] ToByteArray<T>(T[] source) where T : struct
{
GCHandle handle = GCHandle.Alloc(source, GCHandleType.Pinned);
try
{
IntPtr pointer = handle.AddrOfPinnedObject();
byte[] destination = new byte[source.Length * Marshal.SizeOf(typeof(T))];
Marshal.Copy(pointer, destination, 0, destination.Length);
return destination;
}
finally
{
if (handle.IsAllocated)
handle.Free();
}
}
private static T[] FromByteArray<T>(byte[] source) where T : struct
{
T[] destination = new T[source.Length / Marshal.SizeOf(typeof(T))];
GCHandle handle = GCHandle.Alloc(destination, GCHandleType.Pinned);
try
{
IntPtr pointer = handle.AddrOfPinnedObject();
Marshal.Copy(source, 0, pointer, source.Length);
return destination;
}
finally
{
if (handle.IsAllocated)
handle.Free();
}
}
Use it as:
[StructLayout(LayoutKind.Sequential)]
public struct Demo
{
public double X;
public double Y;
}
private static void Main()
{
Demo[] array = new Demo[2];
array[0] = new Demo { X = 5.6, Y = 6.6 };
array[1] = new Demo { X = 7.6, Y = 8.6 };
byte[] bytes = ToByteArray(array);
Demo[] array2 = FromByteArray<Demo>(bytes);
}
This code requires unsafe switch but should be fast. I think you should benchmark these answers...
var bytes = new byte[] { 1, 2, 3, 4 };
var colors = MemCopyUtils.ByteArrayToColor32Array(bytes);
public class MemCopyUtils
{
unsafe delegate void MemCpyDelegate(byte* dst, byte* src, int len);
static MemCpyDelegate MemCpy;
static MemCopyUtils()
{
InitMemCpy();
}
static void InitMemCpy()
{
var mi = typeof(Buffer).GetMethod(
name: "Memcpy",
bindingAttr: BindingFlags.NonPublic | BindingFlags.Static,
binder: null,
types: new Type[] { typeof(byte*), typeof(byte*), typeof(int) },
modifiers: null);
MemCpy = (MemCpyDelegate)Delegate.CreateDelegate(typeof(MemCpyDelegate), mi);
}
public unsafe static Color32[] ByteArrayToColor32Array(byte[] bytes)
{
Color32[] colors = new Color32[bytes.Length / sizeof(Color32)];
fixed (void* tempC = &colors[0])
fixed (byte* pBytes = bytes)
{
byte* pColors = (byte*)tempC;
MemCpy(pColors, pBytes, bytes.Length);
}
return colors;
}
}
Using Parallel.For may give you a significant performance increase.
img = new Color32[byteArray.Length / nChannels]; //nChannels being 4
Parallel.For(0, img.Length, i =>
{
img[i].r = byteArray[i*nChannels];
img[i].g = byteArray[i*nChannels+1];
img[i].b = byteArray[i*nChannels+2];
img[i].a = byteArray[i*nChannels+3];
});
Example on MSDN
I haven't profiled it, but using fixed to ensure your memory doesn't get moved around and to remove bounds checks on array accesses might provide some benefit:
img = new Color32[byteArray.Length / nChannels]; //nChannels being 4
fixed (byte* ba = byteArray)
{
fixed (Color32* c = img)
{
byte* byteArrayPtr = ba;
Color32* colorPtr = c;
for (int i = 0; i < img.Length; i++)
{
(*colorPtr).r = *byteArrayPtr++;
(*colorPtr).g = *byteArrayPtr++;
(*colorPtr).b = *byteArrayPtr++;
(*colorPtr).a = *byteArrayPtr++;
colorPtr++;
}
}
}
It might not provide much more benefit on 64-bit systems - I believe that the bounds checking is is more highly optimized. Also, this is an unsafe operation, so take care.
public Color32[] GetColorArray(byte[] myByte)
{
if (myByte.Length % 1 != 0)
throw new Exception("Must have an even length");
var colors = new Color32[myByte.Length / nChannels];
for (var i = 0; i < myByte.Length; i += nChannels)
{
colors[i / nChannels] = new Color32(
(byte)(myByte[i] & 0xF8),
(byte)(((myByte[i] & 7) << 5) | ((myByte[i + 1] & 0xE0) >> 3)),
(byte)((myByte[i + 1] & 0x1F) << 3),
(byte)1);
}
return colors;
}
Worked about 30-50 times faster than just i++. The "extras" is just styling. This code is doing, in one "line", in the for loop, what you're declaring in 4 lines plus it is much quicker. Cheers :)
Referenced + Referenced code: Here
i am trying to rewrite following code from silverlight to wpf. found here https://slmotiondetection.codeplex.com/
my problem is that WritaeableBitmap.Pixels is missing from wpf. how to achieve that? i understand how it works but i started with C# like week ago.
could you please point me to right direction?
public WriteableBitmap GetMotionBitmap(WriteableBitmap current)
{
if (_previousGrayPixels != null && _previousGrayPixels.Length > 0)
{
WriteableBitmap motionBmp = new WriteableBitmap(current.PixelWidth, current.PixelHeight);
int[] motionPixels = motionBmp.Pixels;
int[] currentPixels = current.Pixels;
int[] currentGrayPixels = ToGrayscale(current).Pixels;
for (int index = 0; index < current.Pixels.Length; index++)
{
byte previousGrayPixel = BitConverter.GetBytes(_previousGrayPixels[index])[0];
byte currentGrayPixel = BitConverter.GetBytes(currentGrayPixels[index])[0];
if (Math.Abs(previousGrayPixel - currentGrayPixel) > Threshold)
{
motionPixels[index] = _highlightColor;
}
else
{
motionPixels[index] = currentPixels[index];
}
}
_previousGrayPixels = currentGrayPixels;
return motionBmp;
}
else
{
_previousGrayPixels = ToGrayscale(current).Pixels;
return current;
}
}
public WriteableBitmap ToGrayscale(WriteableBitmap source)
{
WriteableBitmap gray = new WriteableBitmap(source.PixelWidth, source.PixelHeight);
int[] grayPixels = gray.Pixels;
int[] sourcePixels = source.Pixels;
for (int index = 0; index < sourcePixels.Length; index++)
{
int pixel = sourcePixels[index];
byte[] pixelBytes = BitConverter.GetBytes(pixel);
byte grayPixel = (byte)(0.3 * pixelBytes[2] + 0.59 * pixelBytes[1] + 0.11 * pixelBytes[0]);
pixelBytes[0] = pixelBytes[1] = pixelBytes[2] = grayPixel;
grayPixels[index] = BitConverter.ToInt32(pixelBytes, 0);
}
return gray;
}
`
In order to get the bitmap's raw pixel data you may use one of the BitmapSource.CopyPixels methods, e.g. like this:
var bytesPerPixel = (source.Format.BitsPerPixel + 7) / 8;
var stride = source.PixelWidth * bytesPerPixel;
var bufferSize = source.PixelHeight * stride;
var buffer = new byte[bufferSize];
source.CopyPixels(buffer, stride, 0);
Writing to a WriteableBitmap can be done by one of its WritePixels methods.
Alternatively you may access the bitmap buffer by the WriteableBitmap's BackBuffer property.
For converting a bitmap to grayscale, you might use a FormatConvertedBitmap like this:
var grayscaleBitmap = new FormatConvertedBitmap(source, PixelFormats.Gray8, null, 0d);
Just curious is there a quicker/neater way to achieve this:
double[] source = ... // some initialisation
var target = new double[1, source.Length];
for (var c = 0; c < source.Length; c++)
{
target[0, c] = source[c];
}
Initialiaze the array like this:
double[,] target = { { /* your list of values */ } };
Then you have a two dimentional array with only one row.
Since you are mentioning this is for P/Invoke, BlockCopy is probably reasonable to use:
double[] source = new double [] {1,2,3,4,7,8,9,0};// some initialisation
double[,] target = new double[1, source.Length];
Buffer.BlockCopy(source, 0, target, 0, source.Length * sizeof(double));
Convertion from Double[] src to Byte[] dst
can be efficiently done in C# by fixed pointers:
fixed( Double* pSrc = src)
{
fixed( Byte* pDst = dst)
{
Byte* ps = (Byte*)pSrc;
for (int i=0; i < dstLength; i++)
{
*(pDst + i) = *(ps +i);
}
}
}
How can I do the same for List src ?
I.e. how can I get fixed pointer to array Double[]
included in List ?
Thanks.
I have used these helper methods before:
byte[] GetBytesBlock(double[] values)
{
var result = new byte[values.Length * sizeof(double)];
Buffer.BlockCopy(values, 0, result, 0, result.Length);
return result;
}
double[] GetDoublesBlock(byte[] bytes)
{
var result = new double[bytes.Length / sizeof(double)];
Buffer.BlockCopy(bytes, 0, result, 0, bytes.Length);
return result;
}
An example:
List<double> myList = new List<double>(){ 1.0, 2.0, 3.0};
//to byte[]
var byteResult = GetBytesBlock(myList.ToArray());
//back to List<double>
var doubleResult = GetDoublesBlock(byteResult).ToList();
not sure what you are intending, but I think ... you want
System.Runtime.Interopservices.Marshal.StructToPtr.
You can always use the ToArray() method on the List<Double> object to get a Double[].
You can use reflection to get the reference to the private T[] _items field, in the List instance.
Warning: In your code snippet, you need to make sure dstLength is the minimum of dst and src lengths in bytes, so that you don't try to copy more bytes than what are available. Probably you do so by creating dst with exactly the needed size to match the src, but your snippet doesn't make it clear.
Use the List<T>.ToArray() method and operate on the resulting array.
This might work, but you will have a data loss- content of the array will be 3 and 34 .
List<double> list = new List<double>();
list.Add(Math.PI);
list.Add(34.22);
byte[] arr = (from l in list
select (byte)l).ToArray<byte>();
Why don't you just access the list as usual?
List<double> list = new List<double>();
list.Add(Math.PI);
list.Add(34.22);
byte[] res = new byte[list.Count * sizeof(double)];
unsafe
{
fixed (byte* pres = res)
{
for (int i = 0; i < list.Count; i++)
{
*(((double*)pres) + i) = list[i];
}
}
}
I haven't tested it thoroughly and i seldomly need unsafe code, but it seems to work fine.
Edit: here is another (imo preferable) solution, without unsafe code:
int offset = 0;
for (int i = 0; i < list.Count; i++)
{
long num = BitConverter.DoubleToInt64Bits(list[i]);
for (int j = 0; j < 8; j++)
{
res[offset++] = (byte)num;
num >>= 8;
}
}