Skocz do zawartości

libskry - implementacja techniki lucky imaging/image stacking


Rekomendowane odpowiedzi

Przedstawiam swoją bibliotekę libskry implementującą technikę lucky imaging/image stacking. Napisana w C (C99), więc można skompilować dla dowolnej platformy. Biblioteka jest kluczowym składnikiem programu Stackistry.

Informacje o użytkowaniu i budowaniu ze źródeł znaleźć można w pliku README. Za jakiś czas przygotuję dokładny opis techniczny implementacji.

 

Kod źródłowy do pobrania z https://github.com/GreatAttractor/libskry/releases

Na zachętę jeden z załączonych przykładów, demonstrujący pełny proces stackowania surowego wideo (to tylko ilustracja, bez sprawdzania błędów; praktyczniejszy kod w przykładzie nr 2):

/*
    An unrealistically simple example without any error checking
    (you really should not use code like this!), just to demonstrate
    what objects and in what order must be created.
    
    Do not forget to enable your compiler's C99 mode. By default,
    libskry is built with OpenMP support, so remember to link with
    the necessary libraries. E.g. in case of GCC on Linux, use:
    
        gcc -std=c99 example1.c -lskry -lgomp -L ../bin -I ../include
*/

#include <stddef.h>
#include <stdio.h>
#include <skry/skry.h>


int main(int argc, char *argv[])
{
    SKRY_initialize();

    SKRY_ImgSequence *img_seq = SKRY_init_video_file("sun01.avi", 0);

    // Sometimes we may want to skip certain (e.g. invalid) frames during
    // processing; see the "active" family of functions for details.
    size_t num_steps = SKRY_get_img_count(img_seq);

    SKRY_ImgAlignment *img_alignment =
        SKRY_init_img_alignment(
            img_seq,
            0, 0, // stabilization anchors will be placed automatically
            32, 32, // block radius and search radius for block-matching
            0.33f, // min. relative brightness to place anchors at;
                   // avoid the dark background
            0); // not interested in the result

    // From now on till the end of stacking we must not call any modifying
    // functions on 'img_seq' (those that take a non-const pointer to it),
    // as it is used by 'img_alignment' and subsequent objects.

    size_t step = 1;
    printf("\nImage alignment: step ");
    while (SKRY_SUCCESS == SKRY_img_alignment_step(img_alignment))
    {
        printf("%zu/%zu ", step++, num_steps); fflush(stdout);
        // Eventually, a "step" function returns SKRY_LAST_STEP
        // (or an error code).
    }
    printf(" done.\n");

    SKRY_QualityEstimation *qual_est =
        SKRY_init_quality_est(
            img_alignment,
            40, 3);

    step = 1;
    printf("\nQuality estimation: step ");
    while (SKRY_SUCCESS == SKRY_quality_est_step(qual_est))
    {
        printf("%zu/%zu ", step++, num_steps); fflush(stdout);
    }
    printf(" done.\n");

    SKRY_RefPtAlignment *ref_pt_align =
        SKRY_init_ref_pt_alignment(
            qual_est,
            0, 0, // reference points will be placed automatically
            0.33f, // min. relative brightness to place points at;
                   // avoid the dark background
            // Consider only 30% of the best-quality frame fragments
            // (this criterion later also applies to stacking)
            SKRY_PERCENTAGE_BEST, 30,
            40, // point spacing in pixels
            0);

    step = 1;
    printf("\nReference point alignment: step ");
    while (SKRY_SUCCESS == SKRY_ref_pt_alignment_step(ref_pt_align))
    {
        printf("%zu/%zu ", step++, num_steps); fflush(stdout);
    }
    printf(" done.\n");

    SKRY_Stacking *stacking = SKRY_init_stacking(ref_pt_align, 0, 0);
    step = 1;
    printf("\nImage stacking: step ");
    while (SKRY_SUCCESS == SKRY_stacking_step(stacking))
    {
        printf("%zu/%zu ", step++, num_steps); fflush(stdout);
    }
    printf(" done.\n");

    // Now 'img_seq' can be freely accessed again, if needed.

    // The stack is a mono or RGB image (depending on 'img_seq')
    // with 32-bit floating point pixels, so we need to convert it
    // before saving as a 16-bit TIFF.
    SKRY_Image *img_stack_mono16 = SKRY_convert_pix_fmt(
                                    SKRY_get_image_stack(stacking),
                                    SKRY_PIX_RGB16);
    SKRY_save_image(img_stack_mono16, "sun01_stack.tif", SKRY_TIFF_16);
    SKRY_free_image(img_stack_mono16);


    // The order of freeing is not important
    SKRY_free_stacking(stacking);
    SKRY_free_ref_pt_alignment(ref_pt_align);
    SKRY_free_quality_est(qual_est);
    SKRY_free_img_alignment(img_alignment);
    SKRY_free_img_sequence(img_seq);

    SKRY_deinitialize();
    return 0;
}
  • Lubię 1
Odnośnik do komentarza
Udostępnij na innych stronach

Dołącz do dyskusji

Możesz dodać zawartość już teraz a zarejestrować się później. Jeśli posiadasz już konto, zaloguj się aby dodać zawartość za jego pomocą.

Gość
Dodaj odpowiedź do tematu...

×   Wklejono zawartość z formatowaniem.   Usuń formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Odnośnik został automatycznie osadzony.   Przywróć wyświetlanie jako odnośnik

×   Przywrócono poprzednią zawartość.   Wyczyść edytor

×   Nie możesz bezpośrednio wkleić grafiki. Dodaj lub załącz grafiki z adresu URL.

×
×
  • Dodaj nową pozycję...

Powiadomienie o plikach cookie

Umieściliśmy na Twoim urządzeniu pliki cookie, aby pomóc Ci usprawnić przeglądanie strony. Możesz dostosować ustawienia plików cookie, w przeciwnym wypadku zakładamy, że wyrażasz na to zgodę.