Author Topic: working on pixel data with PJSR, threading, PJSR documentation  (Read 5348 times)

Offline kwiechen

  • PixInsight Addict
  • ***
  • Posts: 186

1) Is it possible to bulk read and write image pixel data without iterating width/height and using Image.sample()/Image.setSample()?

2) Is it possible to start threads to take heavy computation off the main thread (and to use my 6 core Xeon)?

3) I am missing the PJSR documentation. The link
   
http://pixinsight.com/doc/pjsr/objects/Matrix/Matrix.html gives 404.

Kai

Offline Juan Conejero

  • PTeam Member
  • PixInsight Jedi Grand Master
  • ********
  • Posts: 7111
    • http://pixinsight.com/
Quote
1) Is it possible to bulk read and write image pixel data without iterating width/height and using Image.sample()/Image.setSample()?

Yes. You can use the following methods of the Image object:

void Image.getSamples( Array samples[, Rect rect=0[, int channel=-1]] )

Reads pixel values from the specified rectangular area of a channel of the image. If the specified rectangle rect is a null rectangle (which is the default value), the current rectangular selection is used. If the specified channel index is < 0, the currently selected channel is used. Pixel values are returned in the specified samples samples. For example:

var A = [];
var I = new Image;
// ...
// Using specified coordinates
I.getSamples( A, new Rect( 100, 100, 200, 300 ), 0 );
// Using image selections
I.selectedChannel = 0;
I.selectedRect = new Rect( 100, 100, 200, 300 );
I.getSamples( A );


void Image.setSamples( Array samples[, Rect rect=0[, int channel=-1]] )

Writes pixel values on the specified rectangular area and channel. The rectangular and channel selections work the same as Image.getSamples().

In addition, you can use image iterators.  There are sample iterators, which iterate pixel components on a single channel of the image, and pixel iterators, which iterate pixels from a range of channels. The relevant methods are the following:

void Image.initSampleIterator( [Rect r=0[, int channel=-1]] )

Initializes sample iteration. The rectangular and channel selections work as the Image.getSamples() method.

void Image.initPixelIterator( [Rect r=0[, int firstChannel=-1[, int lastChannel=-1]]] )

Initializes pixel iteration for the specified channel range. The rectangular selection works as for the Image.getSamples() method. If the range defined by firstChannel and lastChannel is empty, the current channel selection of the image will be used.

Boolean Image.nextSample()

Moves the current sample iterator to the next pixel in the iterated rectangular region. Returns true if the sample iterator points to a valid location within the iterated region, false on an end-of-iteration condition.

Boolean Image.nextPixel()

Moves the current pixel iterator to the next pixel in the iterated rectangular region. Returns true if the pixel iterator points to a valid location within the iterated region, false on an end-of-iteration condition.

Number|Complex Image.sampleValue()

Returns the value of the current sample iterator. This is the pixel component at the current iterator coordinates on the iterated channel.

void Image.setSampleValue( Number|Complex )

Writes the value of the current sample iterator. This changes the value of the pixel component at the current iterator coordinates on the iterated channel.

Vector Image.pixelValue()

Returns the components of the current pixel iterator. The components of the returned vector are the pixel components at the current iterator coordinates on the iterated channel range. The first vector component is the pixel component at the first iterated channel, and so on up to and including the last iterated channel.

void Image.getPixelValue( Vector v )

Equivalent to Image.pixelValue(), but instead of returning a vector of pixel components stores them in the specified vector v.

void Image.setPixelValue( Vector )

Writes the components of the current pixel iterator. The components of the specified vector will replace the pixel components at the current iterator coordinates on the iterated channel range. The first vector component will replace the pixel component at the first iterated channel, and so on up to and including the last iterated channel.

Here is an example with sample iterators. The following script inverts a rectangular region of the blue channel of the active image.

Code: [Select]
var w = ImageWindow.activeWindow;
var v = w.currentView;
v.beginProcess();

var I = v.image;
I.initSampleIterator( new Rect( 250, 250, 1000, 1200 ), 2/*blue*/ );
do
{
   I.setSampleValue( 1 - I.sampleValue() );
}
while ( I.nextSample() );

v.endProcess();

This is an example with pixel iterators. This script computes a color saturation map (where each pixel is proportional to the maximum separation among color components) for the active image and stores it in its red channel:

Code: [Select]
var w = ImageWindow.activeWindow;
var v = w.currentView;
v.beginProcess();

var I = v.image;
I.initPixelIterator();
var x = new Vector;
do
{
   I.getPixelValue( x );
   var d01 = Math.abs( x.at( 0 ) - x.at( 1 ) );
   var d02 = Math.abs( x.at( 0 ) - x.at( 2 ) );
   var d12 = Math.abs( x.at( 1 ) - x.at( 2 ) );
   x.at( 0, Math.max( d01, d02, d12 ) );
   x.at( 1, 0 );
   x.at( 2, 0 );
   I.setPixelValue( x );
}
while ( I.nextPixel() );

v.endProcess();


Quote
2) Is it possible to start threads to take heavy computation off the main thread (and to use my 6 core Xeon)?

No. The JavaScript engine does not support multithreading. This is actually a limitation of the JavaScript language, which might change in a future version of the ECMAScript standard, but predictably not in the short-medium term. If you want to implement parallel processing, you can use the PCL C++ development framework to write a PixInsight module.

I plan on implementing an integrated C++ compiler in PixInsight. When this happens, C++ code will be as portable as JavaScript is now. The idea is to deploy C++ source code that will be compiled dynamically on the user's machine, just as JavaScript, but with all the power and performance of C++ and native code. This is a complex and large project; hopefully I'll start working on it next Fall, along with GPU acceleration.


Quote
3) I am missing the PJSR documentation.

I am slowly starting to work on the PJSR documentation. I hope to have a first set of documents in July, but most of the documentation will be available after Summer (I really need some vacation!).


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

Offline kwiechen

  • PixInsight Addict
  • ***
  • Posts: 186
Juan,

thank you very much for the code examples! This will help me to clean up my current project (something with routine bright field microscopy).

I think it is not necessary to write a comprehensive documentation of PJSR - some parts are self-explanatory and others are standard javascript. For now it may help to concentrate your valuable code snippets covering parts specific to PI/PJSR that are distributed across multiple threads in this forum to a new location (and to add some more ;-).

But there was a preliminary doc for the Matrix object - this is not available any more.

Regarding pcl/C++: there remain high hurdles starting a project compared to Qt/C++ with Visual Studio or QtCreator. A GUI designer, predefined pcl projects and easy debugging within the IDE will help here.

Best regards,

Kai



Offline Andres.Pozo

  • PTeam Member
  • PixInsight Padawan
  • ****
  • Posts: 927
No. The JavaScript engine does not support multithreading. This is actually a limitation of the JavaScript language, which might change in a future version of the ECMAScript standard, but predictably not in the short-medium term. If you want to implement parallel processing, you can use the PCL C++ development framework to write a PixInsight module.
Juan, do you have any plans about implementing web workers? Although they are quite limited perhaps in some cases they could allow a bit of concurrency in some scripts.

Quote from: Juan Conejero
I plan on implementing an integrated C++ compiler in PixInsight. When this happens, C++ code will be as portable as JavaScript is now. The idea is to deploy C++ source code that will be compiled dynamically on the user's machine, just as JavaScript, but with all the power and performance of C++ and native code. This is a complex and large project; hopefully I'll start working on it next Fall, along with GPU acceleration.
I can't wait!!!  ;) ;)

Offline Juan Conejero

  • PTeam Member
  • PixInsight Jedi Grand Master
  • ********
  • Posts: 7111
    • http://pixinsight.com/
Quote
do you have any plans about implementing web workers?

I have no plans to implement them. I think the time and effort to implement them in PixInsight is better invested in a hybrid C++/JavaScript model, and/or in the embedded C++ compiler.

Another interesting possibility is running several JavaScript runtimes concurrently. This is perfectly doable (Firefox does this with SpiderMonkey for example). The only problem is that runtimes must be isolated in terms of access to JS objects (e.g., a variable declared in a runtime will be unknown for the rest of them), which limits their applicability. This would be no problem for accessing objects external to JavaScript, such as images. Thread synchronization for image access is already implemented in PCL, and exposing it to the JavaScript engine would be quite easy. I have the intention to explore this possibility.

Also worth noting is the fact that many PJSR methods are implemented as multithreaded native routines. For example, this is true for most methods of the Image object. This means that multithreading is already implemented in PJSR behind the scenes. A high-level, JS-specific multithreading model would of course be much more efficient.
« Last Edit: 2014 June 26 01:25:46 by Juan Conejero »
Juan Conejero
PixInsight Development Team
http://pixinsight.com/