Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Propose an API to handle image stacks #410

Open
opatiny opened this issue Dec 1, 2023 · 12 comments
Open

Propose an API to handle image stacks #410

opatiny opened this issue Dec 1, 2023 · 12 comments
Assignees
Labels
stacks Issues relative to the implementation of the `Stack` class

Comments

@opatiny
Copy link
Contributor

opatiny commented Dec 1, 2023

Image stacks are array of images on which different methods can be applied. We want to create a new class Stack. The stacks were already implemented in image-js. Check how they were implemented and propose a new API for image-js-ts.

https://github.com/image-js/image-js/blob/8bfbcc524daafc35c35df62f5d18e7679deae7ee/src/stack/Stack.js

@opatiny
Copy link
Contributor Author

opatiny commented Dec 1, 2023

Here is a first draft of an API to implement stacks in image-js-ts. Any feedback @stropitek , @targos , @lpatiny ?

export class Stack {
  /**
   * The number of images in stack.
   */
  public readonly size: number;

  public constructor(images: Image[], options: StackOptions = {}) {}

  /**
   * Return the image containing the minimum values of all the images in the stack for
   * each pixel .
   */
  public minImage(): Image {}

  /**
   * Return the image containing the maximum values of all the images in the stack for
   * each pixel .
   */
  public maxImage(): Image {}

  /**
   * Return the image containing the median values of all the images in the stack for
   * each pixel .
   */
  public medianImage(): Image {}

  /**
   * Return the image containing the average values of all the images in the stack for
   * each pixel .
   */
  public averageImage(): Image {}

  /**
   * Get the histograms of all the images of the stack.
   */
  public getHistograms(): Uint32Array {}
  /**
   * Get the global histogram of the stack.
   */
  public getHistogram(): Uint32Array {}

  /**
   * Return an array containing the maximum values of each image of the stack.
   */
  public max(): number[] {}

  /**
   * Return an array containing the minimum values of each image of the stack.
   */
  public min(): number[] {}

  /**
   * Align all the images of the stack on the image at the given index.
   * @param refIndex - The index of the reference image.
   */
  public alignImages(refIndex: number): Stack {}

  /**
   * Crop all the images of the stack to desired dimensions.
   * @param options - The cropping options.
   */
  public crop(options: CropOptions): Stack {}

  /**
   * Add all the images of the stack and return a 16 bits image containing the sum.
   */
  public sum(): Image {}
}

export interface CropOptions {
  /**
   * The top left corner of the crop rectangle.
   * @default {row: 0, column: 0}
   */
  origin?: Point;
  /**
   * The width of the crop rectangle.
   * @default image width
   */
  width?: number;
  /**
   * The height of the crop rectangle.
   * @default image height
   */
  height?: number;
}

@targos
Copy link
Member

targos commented Dec 1, 2023

Some notes:

  • Specific methods should do something special in the context of a Stack, not just iterate on the images to do the same thing individually
  • To do the same thing on all images, we could have methods similar to arrays like:
    • stack.map that returns a new stack
    • stack.forEach that calls a callback on each image of the stack

@targos
Copy link
Member

targos commented Dec 1, 2023

Should all images of the stack have the same properties (dimensions, bidDepths, etc) ?

@lpatiny
Copy link
Member

lpatiny commented Dec 6, 2023

Should all images of the stack have the same properties (dimensions, bidDepths, etc) ?

Maybe not mandatory but most of the method should just throw if it is not the case. There could be a method that normalize them so that they have the same properties.

@opatiny
Copy link
Contributor Author

opatiny commented Dec 8, 2023

There could be a method that normalize them so that they have the same properties.

What would you expect from a function normalizing the images?

  • resize all images to match user specified dimensions?
  • or crop images to the smallest one?
  • how do you convert the bit depth? do you convert all images to the smallest bit depth?

@opatiny
Copy link
Contributor Author

opatiny commented Dec 8, 2023

Should all images of the stack have the same properties (dimensions, bidDepths, etc) ?

I agree with @lpatiny that the images could have different dimensions, which could be made uniform with a normalize method. However it seems a lot easier to have the same bit depth and color model for all the images imo. Wdyt @targos ?

@targos
Copy link
Member

targos commented Dec 8, 2023

Agreed. This should be validated when the stack is created and images are added to it.

@opatiny
Copy link
Contributor Author

opatiny commented Dec 8, 2023

Would it be interesting to add a method allowing to read all images from a folder and directly create a stack with the images?

@targos
Copy link
Member

targos commented Dec 8, 2023

Maybe but that's difficult to do right. Stacks have an order, which is not necessarily the same as folder iteration order. You also need to know what to read (what if there are multiple image formats in the folder? Or non image files ? ) too many questions that depend on the specific case

@targos
Copy link
Member

targos commented Dec 8, 2023

You can also easily go out of memory with a large folder

@opatiny opatiny added the stacks Issues relative to the implementation of the `Stack` class label Dec 8, 2023
@stropitek
Copy link
Contributor

Were there known issues with extending Array, which is the implementation in legacy image-js?

It gives map, filter, forEach, reduce etc. out of the box.

With this implementation I suppose map would return an array of images (or something else) and not a Stack. We'd need another custom method that maps images to images by returning a Stack.

@targos
Copy link
Member

targos commented Dec 8, 2023

I would not extend array. Its API surface is too large and we want something more abstract.

@stropitek stropitek removed their assignment May 31, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
stacks Issues relative to the implementation of the `Stack` class
Projects
None yet
Development

No branches or pull requests

4 participants