Author Topic: Image Acquisition in PixInsight (Was: When will Pixinsight...)  (Read 78822 times)

Offline David Raphael

  • PixInsight Addict
  • ***
  • Posts: 226
    • Astrofactors CCD Cameras
Re: Image Acquisition in PixInsight (Was: When will Pixinsight...)
« Reply #60 on: 2011 February 06 10:25:08 »
I still can't see how to get around filling each sample individually since there needs to be a conversion from the signed long data to the unsigned int data


Code: [Select]
void PixInsightASCOMDriver::ImageArray(UInt32Image &theImage)
{
//TODO:  This needs to have some sort of time out.
while(!theCameraPtr->ImageReady)
{
Sleep(1000);
}

long *imageData;
SafeArrayAccessData(theCameraPtr->ImageArray.parray, (void **)&imageData);
int dims = SafeArrayGetDim(theCameraPtr->ImageArray.parray);
long ubound1, ubound2, lbound1, lbound2;
SafeArrayGetUBound(theCameraPtr->ImageArray.parray,1,&ubound1);
SafeArrayGetUBound(theCameraPtr->ImageArray.parray,2,&ubound2);
SafeArrayGetLBound(theCameraPtr->ImageArray.parray,1,&lbound1);
SafeArrayGetLBound(theCameraPtr->ImageArray.parray,2,&lbound2);

int sizeX = ubound1 - lbound1;
int sizeY = ubound2 - lbound2;

theImage.AllocateData(sizeX, sizeY);

for(int rowIdx = 0;rowIdx < sizeY; rowIdx++ )
{
UInt32Image::sample* v = theImage.ScanLine(rowIdx);
for(int colIdx = 0;colIdx < sizeX;colIdx++)
{
//v should be pointing to the current row of data we need to fill
v[colIdx] = UInt32Image::sample(imageData[sizeY*rowIdx + colIdx]);
}
}

SafeArrayUnaccessData( theCameraPtr->ImageArray.parray );
}


David Raphael

Offline Juan Conejero

  • PTeam Member
  • PixInsight Jedi Grand Master
  • ********
  • Posts: 7111
    • http://pixinsight.com/
Re: Image Acquisition in PixInsight (Was: When will Pixinsight...)
« Reply #61 on: 2011 February 06 13:56:36 »
Hi David,

So if I understand it correctly, CCD raw pixel data are being acquired (through ASCOM) as signed 32-bit integers? Seems pretty odd since one might expect unsigned 16-bit integers, but if that's what ASCOM provides, then we'll have to deal with it.

So the key question here is: what numeric range are the input data referred to? In simpler words, which value corresponds to the "no signal" state (black) and which value corresponds to "full signal" (white)? Are we working with data in [0,65535] (stored as int32), or are the data bounded differently? We need to know both bounds in order to translate the input data into an output PixInsight/PCL image.

Along with that, I have a couple recommendations. First, I suggest you use an UInt16Image, instead of UInt32Image, as raw data are 16-bit unsigned pixel values (despite the way they are being provided by ASCOM).

Second, you don't need to work row by row. PixInsight/PCL images store each plane (or channel) as a contiguous block. Since it seems that your input data are also stored as a contiguous block:

Quote
imageData[sizeY*rowIdx + colIdx]

then you don't need ScanLine() and the like. Your code to transfer ASCOM data to a PI/PCL image can be simpler and faster; something like this snippet:

UInt16Image theImage;
// ...
theImage.AllocateData( sizeX, sizeY );
uint16* piImageData = *theImage;
for ( size_type i = 0, N = theImage.NumberOfPixels(); i < N; ++i )
   *piImageData++ = ASCOMDataToPI( *imageData++ );


where ASCOMDataToPI() is a function that you must define to convert a source pixel value into an output 16-bit pixel value in the range [0,65535]; its prototype would be:

uint16 ASCOMDataToPI( int32 );

The above snippet assumes that you're working with monochrome images; for multichannel images the code should be slightly more complex to work on several pixel planes.

So what's the input range of the data as it is being provided by ASCOM?
Juan Conejero
PixInsight Development Team
http://pixinsight.com/

Offline David Raphael

  • PixInsight Addict
  • ***
  • Posts: 226
    • Astrofactors CCD Cameras
Re: Image Acquisition in PixInsight (Was: When will Pixinsight...)
« Reply #62 on: 2011 February 06 14:17:59 »
What is returned is a SAFEARRAY of type Long.  COM doesn't support unsigned integers.

The ASCOM standard provides a method: ElectronsPerADU - which I think we can use to figure out what kind of data each camera uses...

But in the meantime, let's assume that the data range is -32768 to 32767 - either way there are signed values from what I see in the raw data so far. 






David Raphael

Offline David Raphael

  • PixInsight Addict
  • ***
  • Posts: 226
    • Astrofactors CCD Cameras
Re: Image Acquisition in PixInsight (Was: When will Pixinsight...)
« Reply #63 on: 2011 February 06 14:30:29 »
so here is what I have so far:

I'm using long here since that is what is returned from the ASCOM array
Code: [Select]
uint16 PixInsightASCOMDriver::ASCOMDataToPi( long _i )
{
return _i + 32768;
}

And I made the change you suggested:
Code: [Select]
void PixInsightASCOMDriver::ImageArray(UInt16Image &theImage)
{
long *imageData;
SafeArrayAccessData(theCameraPtr->ImageArray.parray, (void **)&imageData);
int dims = SafeArrayGetDim(theCameraPtr->ImageArray.parray);
long ubound1, ubound2, lbound1, lbound2;
SafeArrayGetUBound(theCameraPtr->ImageArray.parray,1,&ubound1);
SafeArrayGetUBound(theCameraPtr->ImageArray.parray,2,&ubound2);
SafeArrayGetLBound(theCameraPtr->ImageArray.parray,1,&lbound1);
SafeArrayGetLBound(theCameraPtr->ImageArray.parray,2,&lbound2);

int sizeX = ubound1 - lbound1;
int sizeY = ubound2 - lbound2;

theImage.AllocateData(sizeX, sizeY);

uint16 *piImageData = *theImage;
for( size_type i = 0, N = theImage.NumberOfPixels(); i < N; ++i)
*piImageData++ = ASCOMDataToPi( *imageData++ );

}

Now, the code that calls this is handing a reference to an UInt16Image...however, I am struggling with this.

Code: [Select]
  void ImageAcquisitionSettingsInterface::TestImage()
  {
  activeCamera->SetConnected(true);
  activeCamera->StartExposure(1);
  Console().WriteLn("taking exposure");
  while(!activeCamera->ImageReady())
  {
  //Console().WriteLn("camera not ready yet...");
  }
  activeCamera->SetLogger(&theLogger);
  UInt16Image img;
  activeCamera->ImageArray(img);
  ImageWindow newImageWindow(img.Bounds().Height(),img.Bounds().Width());
  Image* vImage = newImageWindow.MainView().Image() = img; 
  newImageWindow.Show();
  }

This is just a test method.  I'm trying to create an image window with the resulting data.  I've iterated on this a bit, and I think I'm doing something really wrong :-( 
David Raphael

Offline David Raphael

  • PixInsight Addict
  • ***
  • Posts: 226
    • Astrofactors CCD Cameras
Re: Image Acquisition in PixInsight (Was: When will Pixinsight...)
« Reply #64 on: 2011 February 06 14:42:38 »
I just want to set the value of an Image in a ImageWindow...why is this hard for me to figure out???

Sorry if I sound a little frustrated...I am just not used to C++ templates...they really make my head hurt.

David Raphael

Offline Juan Conejero

  • PTeam Member
  • PixInsight Jedi Grand Master
  • ********
  • Posts: 7111
    • http://pixinsight.com/
Re: Image Acquisition in PixInsight (Was: When will Pixinsight...)
« Reply #65 on: 2011 February 06 14:57:03 »
You must work in the opposite order: create your image window first, then get a reference to its main view (images are owned by views in PixInsight), and then a reference to the image in that view. This is an example:

Code: [Select]
ImageWindow window ( sizeX,         // width
                     sizeY,         // height
                     1,             // numberOfChannels
                     16,            // bitsPerSample
                     false,         // floatSample
                     false,         // color
                     true,          // initialProcessing
                     "camera_test"  // id
           );

View view = window.MainView();

ImageVariant v = view.Image();

UInt16Image* image = static_cast<UInt16Image*>( v.AnyImage() );

// ...

uint16* piImageData = **image;
for ( size_type i = 0, N = image->NumberOfPixels(); i < N; ++i )
   *piImageData++ = ASCOMDataToPI( *imageData++ );

// ...

window.Show();
window.ZoomToFit( false ); // don't allow zoom > 1

You actually don't need templates here, since you know in advance that your output image is a 16-bit unsigned image. That's why we can use the static_cast<>() in the above code.

Let me know if it works this way. We'll get it working, you can be sure about that ;)
Juan Conejero
PixInsight Development Team
http://pixinsight.com/

Offline David Raphael

  • PixInsight Addict
  • ***
  • Posts: 226
    • Astrofactors CCD Cameras
Re: Image Acquisition in PixInsight (Was: When will Pixinsight...)
« Reply #66 on: 2011 February 06 15:12:44 »
FIRST LIGHT!!!

Heheh.  Thanks Juan.  I was ready to cut off a finger :-)

We now have image data coming from a camera to PixInsight...and it loads the drivers dynamically through user configuration via the UI - this code works on Windows and OS X so far...but I only have a real driver written for ASCOM support on Windows.

Here is a screen shot of my first light.

David Raphael

Offline Juan Conejero

  • PTeam Member
  • PixInsight Jedi Grand Master
  • ********
  • Posts: 7111
    • http://pixinsight.com/
Re: Image Acquisition in PixInsight (Was: When will Pixinsight...)
« Reply #67 on: 2011 February 06 15:24:22 »
WOW!   8)

Well done! Extremely well done! This is a milestone in the history of PixInsight and we must celebrate it.

Now to dream with this working on Linux and Mac OS X ... :)

Juan Conejero
PixInsight Development Team
http://pixinsight.com/

Offline zvrastil

  • PixInsight Addict
  • ***
  • Posts: 179
    • Astrophotography
Re: Image Acquisition in PixInsight (Was: When will Pixinsight...)
« Reply #68 on: 2011 February 07 00:29:17 »
Hello David,

I'm glad you managed the safearray in the end. It's really a big step forward. Two notes:

1) I would be really surprised if ASCOM images are scaled to -32768..32768. They're using long (= int) so the actual range of one value is -2,147,483,648 to 2,147,483,647. The actual range of the provided values should be 0 to Camera.MaxADU (-> property of the camera driver).

2) The image on your screenshot has all pixels in each row equal. If this is not somehow caused by camera, it is likely some bug in your code, causing every row to be filled with only one pixel value. Worth of checking.

Good work.

regards, Zbynek

Offline Emanuele

  • PixInsight Addict
  • ***
  • Posts: 270
Re: Image Acquisition in PixInsight (Was: When will Pixinsight...)
« Reply #69 on: 2011 February 07 04:29:31 »
David,
Sorry to interrupt the programming discussion but I am typing this to congratulate you with this milestone! :)
I can see myself already acquiring with PI on a beautiful starry night!

Thank you!
E.

Offline David Raphael

  • PixInsight Addict
  • ***
  • Posts: 226
    • Astrofactors CCD Cameras
Re: Image Acquisition in PixInsight (Was: When will Pixinsight...)
« Reply #70 on: 2011 February 07 04:54:51 »
Hello David,

I'm glad you managed the safearray in the end. It's really a big step forward. Two notes:
Thanks
Quote
1) I would be really surprised if ASCOM images are scaled to -32768..32768. They're using long (= int) so the actual range of one value is -2,147,483,648 to 2,147,483,647. The actual range of the provided values should be 0 to Camera.MaxADU (-> property of the camera driver).
I was surprised too.  The values coming from the driver are negative - but it may just be a bug.  Their is definitely more work to do.
Quote
2) The image on your screenshot has all pixels in each row equal. If this is not somehow caused by camera, it is likely some bug in your code, causing every row to be filled with only one pixel value. Worth of checking.
It is the camera - I compared it to Maxim.  It is just a CMOS guider pointed at junk on my desk.  It has a line noise reduction routine - which creates a strange BIAS pattern.
David Raphael

Offline David Raphael

  • PixInsight Addict
  • ***
  • Posts: 226
    • Astrofactors CCD Cameras
Re: Image Acquisition in PixInsight (Was: When will Pixinsight...)
« Reply #71 on: 2011 February 07 07:04:03 »
The more I think about it - the more I think you are right, Zbynek...it doesn't make any sense for the values to be negative.  I probably need to revisit this code:

Code: [Select]
  long *imageData;
  SafeArrayAccessData(theCameraPtr->ImageArray.parray, (void **)&imageData);

Because this is where I am seeing negative values.  You mention that they are using long (=int), but I see them using Long - isn't that a 64-bit value?
Here is a reference from MS:
http://msdn.microsoft.com/en-us/library/y595sc15.aspx

Either way, it does seem odd to me that there would be any negative values.  ESPECIALLY with a property like MaxADU - it would have broken meaning if there were negative values I think.

I am going to take a much closer look at all of this now that the basic plumbing is in place.

Thanks for your feedback - I greatly appreciate it.

-dave


David Raphael

Offline zvrastil

  • PixInsight Addict
  • ***
  • Posts: 179
    • Astrophotography
Re: Image Acquisition in PixInsight (Was: When will Pixinsight...)
« Reply #72 on: 2011 February 07 08:56:36 »
Because this is where I am seeing negative values.  You mention that they are using long (=int), but I see them using Long - isn't that a 64-bit value?
Here is a reference from MS:
http://msdn.microsoft.com/en-us/library/y595sc15.aspx

Hi Dave,

in C++ and on both 32bit and (oddly enough) 64bit Windows, size of long is equal to 32 bits. The page you're refering to concerns CLR (.NET languages like C# or Visual Basic).
Hope you solve it soon, negative values seem really strange.

BTW, I see on ASCOM pages http://ascom-standards.org/Downloads/PlatformUpdates.htm, that there is an ASCOM Camera Simulator software. Maybe, it could be good tool for development and testing. With it, you should know what to expect. In general, simulators are very handy when writing hardware-dependent code.

regards, Zbynek
« Last Edit: 2011 February 07 09:03:07 by zvrastil »

Offline David Raphael

  • PixInsight Addict
  • ***
  • Posts: 226
    • Astrofactors CCD Cameras
Re: Image Acquisition in PixInsight (Was: When will Pixinsight...)
« Reply #73 on: 2011 February 07 09:37:30 »
Regarding Long - since the ASCOM spec says that it is Long - I think that I may need to pass a different type to pull data from the array.  It makes sense that copying data from a 64bit to a 32bit would be a problem  ;-)

I've been posting messages regarding the camera simulator to the ASCOM-Talk board...it is not working for me currently.  I've tried 2 different versions of the simulator too.  I agree - having the simulator would be grand...

I received definite confirmation that there should be no negative values...

David Raphael

Offline Carlos Milovic

  • PTeam Member
  • PixInsight Jedi Master
  • ******
  • Posts: 2172
  • Join the dark side... we have cookies
    • http://www.astrophoto.cl
Re: Image Acquisition in PixInsight (Was: When will Pixinsight...)
« Reply #74 on: 2011 February 07 09:48:03 »
You may try using int32 (defined by the PCL) instead of long...
Regards,

Carlos Milovic F.
--------------------------------
PixInsight Project Developer
http://www.pixinsight.com