C
C#2mo ago
nope

Converting ushort pointer to something I can use to display images

I have a pointer, knowing height and width what is the best way to display said image? I am not contrary to converting it to 8 bit. Just trying to understand how I can use said pointer since obviously no image processing extension in c# can deal with it
136 Replies
nope
nope2mo ago
I am open to using any extension btw
maxmahem
maxmahem2mo ago
Span has a ctor that takes a pointer and a length, so you can construct one using a pointer, and then go from there to an array, or construct an image directly if you have a method that can take a span.
nope
nope2mo ago
What is "one" here? Sorry I don't get it
maxmahem
maxmahem2mo ago
You can make a Span using a pointer and a length. Which you will then be more easily able to manage within C#.
nope
nope2mo ago
Is it as simol as Span <ushort> array = image? Knowing ushort * image is the pointer
maxmahem
maxmahem2mo ago
mmm... more like...
Span<ushort> imageSpan = new(dataPointer, length);
var image = Image.Convert(imageSpan);
Span<ushort> imageSpan = new(dataPointer, length);
var image = Image.Convert(imageSpan);
Presuming you have some library that takes a span to construct an image. Alternatively you might need to do something like...
Span<ushort> imageSpan = new(dataPointer, length);
var image = new Image(height, width, otherSetting);
for(int index = 0; index < imageSpan.Length; index++) {
image[index] = pixelConverter(imageSpan[index]);
}
Span<ushort> imageSpan = new(dataPointer, length);
var image = new Image(height, width, otherSetting);
for(int index = 0; index < imageSpan.Length; index++) {
image[index] = pixelConverter(imageSpan[index]);
}
It depends on what format data you have, what format of data you need, and what library you are using to manage the images in. The BCL doesn't really have a standard "image" type.
nope
nope2mo ago
Okay, I'll try with emgu Okay the problem is I don't see an extension that uses span, an alternative would be to use two nested for loops and copying the data from the pointer but that may take too long
maxmahem
maxmahem2mo ago
what library are you using?
nope
nope2mo ago
Emgu at the moment I started with Imageshaep but it doesn't handle grayscale well so I turned to Emgu
maxmahem
maxmahem2mo ago
looks like this method takes a ptr, though I imagine you'll need to be careful with the depth and what not https://emgu.com/wiki/files/3.0.0/document/html/c0cc246f-7c2a-e2c9-7b98-f2a98beef077.htm looks kind of dangerous though. What's your endgoal here?
nope
nope2mo ago
Being able to display and save said image, it can be displayed at lower quality though. That isn't as important
maxmahem
maxmahem2mo ago
so like WPF to display?
nope
nope2mo ago
Yeah, can be on a win form too if it's better. Learning c# so I don't exclude anything
maxmahem
maxmahem2mo ago
BitmapSource.Create Method (System.Windows.Media.Imaging)
Creates a new BitmapSource that has the specified properties and options.
maxmahem
maxmahem2mo ago
note that like the method that takes a pointer also doesn't copy so you need to be careful with the unmanged memory. ultimately if you want to copy and/or transform the data, looping through all the end points and copying/translating them may be necessary with a for loop at some point. I wouldn't worry about the performance of this unless and untill you identify it as a bottleneck.
reflectronic
reflectronic2mo ago
you'll need to say what exactly the the format of the data is i assume this is the same library as the other question
nope
nope4w ago
Yeah it's the same library, UINT_16 grayscale In c# ushort Yes, this is what I have so far unsafe public void button1_Click(object sender, EventArgs e) { var device = new NativeMethods.StnDevice(); device.ImageAcquired += Device_ImageAcquired; device.connect(); device.StartAcquisition(); unsafe void Device_ImageAcquired(ushort bank, ushort frame, int width, int height, ushort* image, bool moreAvailable) {
int i, j, counter; counter = 0; Image<Gray, UInt16> img = new Image<Gray, UInt16>(width, height); // if i find a way to convert the pointer into an array with Marshal maybe i can use the code below for now i copy uint16 by uint16 // Buffer.BlockCopy(image, 0, img.Data, 0, width*height * sizeof(ushort)); for (i = 0; i < height; i++) { for (j = 0; j < width; j++) { img.Data[i, j, 0] = image[counter]; counter++; } } try { imageBox1.Image = img; textBox1.AppendText("we're in there"); } catch (Exception ex) { MessageBox.Show(ex.Message); }
} device.disconnect(); }
reflectronic
reflectronic4w ago
is there more you can say about what "UINT_16 grayscale" is? does that mean that each pixel is one from 65536 different shades of gray? it is very very difficult to write this code without knowing what exactly the pixels are
nope
nope4w ago
Yes In c++ the pixels were a const uint16_t* That's why it's a ushort* in c# now
reflectronic
reflectronic4w ago
what is this Image<Gray, UInt16> thing that you are trying to use is it from a library that you have?
nope
nope4w ago
Yeah i'm trying to display it by using emgu. I can use other libraries though
reflectronic
reflectronic4w ago
what is imageBox1
nope
nope4w ago
It's the picturebox given by emgucv
reflectronic
reflectronic4w ago
is it the thing from emgu i see is there something about this code which is not working
nope
nope4w ago
It's not showing anything on screen. I used append text to check if it even ran Device_ImageAcquired and it doesn't
reflectronic
reflectronic4w ago
ok, well, if it's not running Device_ImageAcquired then that is an issue
nope
nope4w ago
Yeah when I click the button on the form it doesn't show anything Oh wait when I ran in debug it didn't show any errors but in release I get the error System.BadImageFormatException HRESULT: 0x8007000B
reflectronic
reflectronic4w ago
when you built the C++ DLL, what configuration did you use when building it
nope
nope4w ago
X86 And I'm using that when I'm still using x86 now Yeah i saw that online
reflectronic
reflectronic4w ago
so, you don't have "Prefer 32-bit" disabled in your Release configuration in the C# project properties
nope
nope4w ago
Oh i did have the planfrom target as x64 Still doesn't show an image though
reflectronic
reflectronic4w ago
when you said that you used append text to check if it even ran Device_ImageAcquired what does that mean exactly if it really is not running it is going to be extremely difficult to debug this i do not know at all how this C++ library works or is supposed to be used
nope
nope4w ago
Okay so device.ImageAcquired += Device_ImageAcquired should automatically call Device_ImageAcquired every time
reflectronic
reflectronic4w ago
well, yes, it's certainly supposed to do that i don't know why it is not doing that
nope
nope4w ago
private unsafe void OnImageAcquired(ushort bank, ushort frame, int width, int height, ushort* image, bool moreAvailable) { Task.Run(() => ImageAcquired?.Invoke(bank, frame, width, height, image, moreAvailable)); } Is there an error here?
reflectronic
reflectronic4w ago
i do not think there is an error in the code that i wrote, no that is why it is hard to figure it out if you put a MessageBox.Show inside of OnImageAcquired does it show anything?
nope
nope4w ago
I put message box.show in private unsafe void OnImageAcquired and it didn't show anything Wait, when is OnImageAcquired supposed to be used in the code?
reflectronic
reflectronic4w ago
it is what the C++ calls
nope
nope4w ago
Ok Check dm I sent a libeshare so you can see all the code Either way if you'd rather not do that I can just Share the library to you Oh now I know why it doesn't work @reflectronic "don't call any st::stn_device method from this callback, result of such a call is undefined" Well they could have been more explicit with that but yeah that's probably why Also while that may be the problem there is also another issue, wether the panel is connected or not connect and start acquisition don't give back exceptions which means everything else may be correct and the connection and acquisition part are the issue Ok yeah the callback is very dangerous
reflectronic
reflectronic4w ago
sorry, i went to bed i don't think this is the problem--we don't use anything from the C++ object in the callback
nope
nope4w ago
I can send it again when I have the PC on hand it's not mine The only advice that I've found online regarding this is this "Create a byte array of sufficient size, use" "fixed" to get a pointer to the byte array, and call Buffer.MemoryCopy to copy the actual data, You could also create a pool of buffers to reuse" @reflectronic
reflectronic
reflectronic4w ago
this doesn't help because the Device_ImageAcquired is not called in the first place
nope
nope4w ago
Maybe it is called, messagebox doesn't work quite as well in program.cs it should be used in the form from what I understand What code would I use to see if its actually called?
reflectronic
reflectronic4w ago
you would usually use a debugger and set a breakpoint
nope
nope4w ago
Nvm Device_ImageAcquired isn't called I'm talking About the task.run Meant to say that OnImageAcquired maybe is called and Device_ImageAcquired is the problem. Though I have no idea why that would be the case
reflectronic
reflectronic4w ago
i would doubt it
nope
nope4w ago
I'm using visual studio 2019,judt specifying in case that could change anything Ok it's almost 2 am that's all from me for now, thank you for your help as always ifdef _WIN32 _CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF); WSADATA wsa_data; if (WSAStartup(MAKEWORD(2, 2), &wsa_data) != 0) { sync_print(L"WSAStartup failed"); return 1; } #endif sync_print(program_name, " started. ", configuration, " ", platform); sync_print(" SDK version ", stn::stn_device::get_sdk_version()); device dev; if(!set_parameters(dev)) return 1; if(!connect(dev)) return 1; Bool result = acquire_images(dev); disconnect(dev); return (result? 0 : 1); // 0 - success, 1 - failure This was the actual main before it was modified @reflectronic
reflectronic
reflectronic4w ago
ok. so. when you showed me the code before and i asked "is that all you need to do" and you said "yes" the answer was not actually "yes"
nope
nope4w ago
As i said connect and start acquisition don't give errors even when I don't have the pal. Comnect
reflectronic
reflectronic4w ago
what does set_parameters do because you did not show me this set_parameters last time
nope
nope4w ago
I already added set parameters It sets the general and advanced parameters I do apologised though. The code isn't mine and I'm trying to help a person declspec(dllexport) bool set_parameters_general(dotnet_device* device) { try { return &dotnet_device::set_general_parameters; } catch (...) { return false; } } declspec(dllexport) bool set_parameters_advanced(dotnet_device* device) { try { return &dotnet_device::set_advanced_parameters; } catch (...) { return false; } } declspec(dllexport) bool set_parameters_logging(dotnet_device* device) { try { return &dotnet_device::set_logging_parameters; } catch (...) { return false; } } declspec(dllexport) bool set_parameters_acquisition(dotnet_device* device) { try { return &dotnet_device::set_acquisition_parameters; } catch (...) { return false; } } internal static extern bool SetGeneralParameters(StnDeviceHandle device); [DllImport("Dll2.dll", EntryPoint = "set_parameters_advanced")] internal static extern bool SetAdvancedParameters(StnDeviceHandle device); [DllImport("Dll2.dll", EntryPoint = "set_parameters_logging")] internal static extern bool SetLoggingParameters(StnDeviceHandle device); [DllImport("Dll2.dll", EntryPoint = "set_parameters_acquisition")] internal static extern bool SetAcquisitionParameters(StnDeviceHandle device); public void SetGenParameters() { if (!NativeMethods.SetGeneralParameters(handle)) { throw new Exception("couldn't set parameters"); } } public void SetLogParameters() { if (!NativeMethods.SetLoggingParameters(handle)) { throw new Exception("couldn't set parameters"); } } public void SetAdvParameters() etc Already put this code The problem is even before that as when I try to connect it does not give any error when it should when there is no connectiin
reflectronic
reflectronic4w ago
your set_parameters_general is not implemented correctly it does not do anything it just returns true always to be clear: the C++ program works, right?
nope
nope4w ago
Yes the c++ program runs
reflectronic
reflectronic4w ago
if you delete set_parameters from your C++ program does it still work?
nope
nope4w ago
No
reflectronic
reflectronic4w ago
ok. so. this is very good it means that, it's very likely that the problem is this which means that, the fix is probably very easy can you show the C++ code for set_parameters
nope
nope4w ago
bool set_parameters(device& dev) { if (!set_general_parameters(dev)) return false; if (!set_advanced_parameters(dev)) return false; if (!set_logging_parameters(dev)) return false; if (!set_acquisition_parameters(dev)) return false; return true; } bool set_general_parameters(device& dev) { stn::general_parameters p; if (!dev.get_general_parameters(p)) { sync_print(utilities::stn_error_to_string("get_general_parameters")); return false; } // In most cases, general_parameters default values are OK. // You may need to change something in general_parameters, for example, // if you want to use non-default device IP address. // Uncomment the following code fragment to get this functionality. #if 0 p.address = "192.168.100.100"; // Change other parameters if necessary, see details in general_parameters definition. if (!dev.set_general_parameters(p)) { sync_print(utilities::stn_error_to_string("set_general_parameters"); return false; } #endif sync_print(FUNCTION, " Device IP address: ", p.address); return true; } bool set_advanced_parameters(device& dev) { stn::advanced_parameters p; if (!dev.get_advanced_parameters(p)) { sync_print(utilities::stn_error_to_string("get_advanced_parameters")); return false; } // For better performance, change default advanced parameters. p.use_non_paged_buffer = true; p.image_socket_input_buffer = stn::image_socket_input_buffer_max; p.table_socket_output_buffer = stn::image_socket_output_buffer_max; p.host_eth_speed = stn::ethernet_speed::h1g; if (!dev.set_advanced_parameters(p)) { sync_print(utilities::stn_error_to_string("set_advanced_parameters")); return false; } sync_print(FUNCTION, " Ethernet speed: ", stn::stn_names::ethernet_speed_to_string(p.host_eth_speed)); return true; }
reflectronic
reflectronic4w ago
can you show what e.g. dotnet_device::set_general_parameters is? did you basically just copy set_general_parameters, but replaced dev with this?
nope
nope4w ago
Yes Btw i did send you the live share link
reflectronic
reflectronic4w ago
yeah, so, you need to replace return &dotnet_device::set_general_parameters; with return device->set_general_parameters(); does the live share have the C++ in it too
nope
nope4w ago
Yeah
reflectronic
reflectronic4w ago
can you go to the file with dotnet_device in it oh, it's this one
nope
nope4w ago
Yeah
reflectronic
reflectronic4w ago
you need to copy the code that you just pasted in like, this whoel set_parameters thing needs to be pasted in here
nope
nope4w ago
Done Or do you mean it needs to be pasted inside the "try"?
reflectronic
reflectronic4w ago
i will move them into dotnet_device oh, i can't edit this file can you move these functions inside of dotnet_device put them right below dotnet_device(image_acquired_callback* dotnet_callback) : dotnet_callback(dotnet_callback) {} for each of these functions, delete the parameter device& dev then, everywhere it does something like dev.get_advanced_parameters(...), replace it with get_advanced_parameters(...) like, just delete dev. ok. you changed all of these functions to make them not work return &dotnet_device::connect; is the exact same as return true; your connect function does nothing. none of them do anything does return device->connect(); not work?
nope
nope4w ago
Yeah i mentioned it
reflectronic
reflectronic4w ago
. instead of return &dotnet_device::connect; ok. so. it seems to work and now you need to do this for every other thing you changed
nope
nope4w ago
I get the errors dotnetdevice::set... Function does not take 1 arguments And non standard syntax; use & to create a pointer to member
reflectronic
reflectronic4w ago
no, those are old errors. try rebuilding again
nope
nope4w ago
Still get function does not take 1 arguments 233 261 305 The lines Trying to give you writing privileges but it doesnt seem to work
reflectronic
reflectronic4w ago
hold on if you move your cursor to line 176 put it on the "stn_device" then, press F12 on your keyboard
nope
nope4w ago
Done
reflectronic
reflectronic4w ago
ok, i understand what needs to happen can you try building the C++ dll @nope
nope
nope4w ago
Ok Done
reflectronic
reflectronic4w ago
ok, well, now it's failing to connect
nope
nope4w ago
Does it have to do with the first part of this code maybe?
reflectronic
reflectronic4w ago
i think i already did that can you try building and running it again i added some more things so maybe it will print out an error
nope
nope4w ago
It's not doing anything this time Not sure you see the form
reflectronic
reflectronic4w ago
no i don't see the form can you try running it again
nope
nope4w ago
Nvm it works one moment It got into a messagebox loop Okay, now it shows an image, though it's all black
reflectronic
reflectronic4w ago
ok. can you try running it again
nope
nope4w ago
Is that you doing something right now?
reflectronic
reflectronic4w ago
yeah
nope
nope4w ago
Oh my bad
reflectronic
reflectronic4w ago
i am just looking at what it thinks the picture is can you try running again ok. well. there seems to be a picture... i can see it's reading pixels and, like, the pixels are not 0, they are not the same, it seems like it might be working i don't know why it's showing all black for you ok let me try something i am going to try displaying it in a window using a different drawing library
nope
nope4w ago
Ok Oh it may be that the pixel by pixel of emgu is too slow, looked it up online and people were complaining about that
reflectronic
reflectronic4w ago
ok. i have tried something can you try running the application i am not sure if it works
nope
nope4w ago
Dispatcher and monitor do not exist Gotta add a couple "using"?
reflectronic
reflectronic4w ago
can you try again again and again ok, i made a mistake, please hold try again hm is there a place you can have the code save a png file
nope
nope4w ago
Is that the right form to save an image?
reflectronic
reflectronic4w ago
you need to put a path it needs to be somewhere that you can open it
nope
nope4w ago
Yeah that's a path
reflectronic
reflectronic4w ago
ok try running it ok. can you open the png
nope
nope4w ago
It's blank Yeah i can open it
reflectronic
reflectronic4w ago
hm
nope
nope4w ago
Goddammit When the data is saved in c++
reflectronic
reflectronic4w ago
can you try again @nope
nope
nope4w ago
Orig does not exist
reflectronic
reflectronic4w ago
try it again
nope
nope4w ago
Above the name space is how the file is saved in c++ No image is being saved
reflectronic
reflectronic4w ago
yes, but you can't look at the image that makes to see if it's correct so that does not help can you press the button
nope
nope4w ago
Pressed
reflectronic
reflectronic4w ago
did it ask you to reload the project
nope
nope4w ago
No It didn't say I need to stop debugging like before The first time with only the emgu code the imagebox was all black now it doesn't load an image Saying that in case that wasn't part of the plan
reflectronic
reflectronic4w ago
ok let me try something else can you try re-running
nope
nope4w ago
Yeah there were some errors in the form
reflectronic
reflectronic4w ago
is it showing anything
nope
nope4w ago
No I mean in the code The form code is kinda messed up now
reflectronic
reflectronic4w ago
which form code
nope
nope4w ago
Just a} Missing somewhere now
reflectronic
reflectronic4w ago
can you try rebuilding
nope
nope4w ago
Ok now the imagebox is all black Says form1.o is never used ad a warning btw
reflectronic
reflectronic4w ago
can you try again
nope
nope4w ago
Cannot implicitly convert ushort to emgu cv structure gray
reflectronic
reflectronic4w ago
ok hold on
reflectronic
reflectronic4w ago
can you try running it again still black?
nope
nope4w ago
Still all black
reflectronic
reflectronic4w ago
try running it again if you hover over "one" with your mouse what does it tell you hm actually it is sending them back to me ok. uh. are you OK with sending one of these pictures to me it is hard to figure out what is going on when the live share is this laggy i will write some code to save the bytes to a file
nope
nope4w ago
It's because the device takes up all the connection Okay maybe displaying it in 8bit may be the solution
reflectronic
reflectronic4w ago
can you run the program again again
nope
nope4w ago
All black Thank you for your help
reflectronic
reflectronic4w ago
ok hold let me rejoin if you are OK with sharing one of the pictures, can you send the "out.bin" file that is in the bin/Debug
nope
nope4w ago
Wait this is release not debug, one moment let me run it again then
reflectronic
reflectronic4w ago
i see it in the debug folder
nope
nope4w ago
Yeah that's an old out Ok now I'll send it
reflectronic
reflectronic4w ago
and can you start the program again
MODiX
MODiX4w ago
Please don't upload any potentially harmful files @nope, your message has been removed
reflectronic
reflectronic4w ago
send it in DMs
nope
nope4w ago
Sent
reflectronic
reflectronic4w ago
and can you run the program as debug this time
nope
nope4w ago
Yeah i did this time
reflectronic
reflectronic4w ago
are you sure it is running as debug and not as release
nope
nope4w ago
I mean it it on "debug" and "x86" settings If there are others I'm missing I can check
reflectronic
reflectronic4w ago
can you relaunch i just need to see what the size of the image is then i will be able to use this file on my computer and see what needs to happen to get it to show 1792 ok
Want results from more Discord servers?
Add your server
More Posts