astro4j icon indicating copy to clipboard operation
astro4j copied to clipboard

Trimmed Video Luminosity / Most Significant Bits issue

Open vnp85 opened this issue 7 months ago • 7 comments

I think there is an unsigned integer wraparound, perhaps because the trimmed video attempts more than just straightening the curved spectral lines. The burnt out pixels look like still contain information, but with the most significant bit having gone missing, ie modulo / wraparound.

Top: original input Bottom: trimmed video with burnt out pixels

Image

Below, the most significant bit suspicion when a sunspot darkens the light going into the slit

Image

A similar effect can be achieved if I artificially decrease the bit depth when viewing the ser

Image

vnp85 avatar May 02 '25 19:05 vnp85

Does JSol'Ex open the trimmed file correctly? e.g in the player? SER recorders like Sharpcap "lie" about the pixel depth, which forces readers like SER Player or even JSol'Ex to infer the pixel depth.

melix avatar May 02 '25 19:05 melix

I'd say it is royally beyond repair, both the original and the trimmed

Image

Image

vnp85 avatar May 02 '25 19:05 vnp85

Alright. I thought I fixed all these nasty bugs. I guess you don't have the original at hand anymore?

melix avatar May 02 '25 19:05 melix

I ran one of the ser files through PIPP, just ser output, no processing/triming/cropping/debayring, nothing,

to see what happens if I try to load that into JSolEx,

same file

Image

vnp85 avatar May 02 '25 19:05 vnp85

I do have the original, I am drowning in dozens of terabytes of unprocessed raw ser videos, it is rather excruciating actually, the pressure to decide what to keep, for how long, and what to delete, and when would have that deleted file come in handy

vnp85 avatar May 02 '25 19:05 vnp85

narnia link coming

vnp85 avatar May 02 '25 19:05 vnp85

http://narnia.go.ro/seagate2tb.php?mask=2025-05-01

vnp85 avatar May 02 '25 19:05 vnp85

I noticed this is a recurring issue, this is in 3.2.1. At around small gain values and millisecond exposures. The original ser video is not saturated

Image

vnp85 avatar May 28 '25 09:05 vnp85

This problem still persists in 3.2.2, the video is recorded at about 10ms, with gain 0, saturation kept at 70-80% max (worse when reaching 90%)

Image

vnp85 avatar Jul 05 '25 07:07 vnp85

The problem present in 3.3.1 also.

vnp85 avatar Jul 08 '25 08:07 vnp85

Correct, I haven't figured that out yet.

melix avatar Jul 08 '25 08:07 melix

I found this in your code

https://github.com/melix/astro4j/blob/main/jserfile/src/main/java/me/champeau/a4j/ser/SerFileReader.java#L180C13-L180C68

I thought maybe there is something weird in my files, wrote some code to dump what's in the .ser files' header -- nothing stands out:

Here's a working instance (which saturates pixels that are saturated in the original, H alpha, don't care about the context)

{
    "1_FileID": "LUCAM-RECORDER",
    "2_LuID": "4\\0x12\\0x00\\0x00",
    "3_ColorID": 0,
    "4_LittleEndian": 0,
    "5_ImageWidth": 3200,
    "6_ImageHeight": 180,
    "7_PixelDepthPerPlane": 16,
    "8_FrameCount": 10874,
    "9_Observer": "Observer                                ",
    "10_Instrument": "ZWO ASI678MM                            ",
    "11_Telescope": "Telescope                               ",
    "12_DateTime": "Tue, 08 Jul 2025 13:30:43 +0200",
    "13_DateTime_UTC": "Tue, 08 Jul 2025 10:30:43 +0200",
    "frameSize_Bytes": 1152000,
    "imageDataSize_Bytes": 12526848000,
    "headerSize_Bytes": 178,
    "filesize_Bytes": 12526935170,
    "tailsize_Bytes": 86992,
    "tailsizePerFrame_Bytes": 8
}

and the input file's header that generates the lost bits output

{
    "1_FileID": "LUCAM-RECORDER",
    "2_LuID": "4\\0x12\\0x00\\0x00",
    "3_ColorID": 0,
    "4_LittleEndian": 0,
    "5_ImageWidth": 3400,
    "6_ImageHeight": 800,
    "7_PixelDepthPerPlane": 16,
    "8_FrameCount": 986,
    "9_Observer": "Observer                                ",
    "10_Instrument": "ZWO ASI678MM                            ",
    "11_Telescope": "Telescope                               ",
    "12_DateTime": "Tue, 08 Jul 2025 11:53:23 +0200",
    "13_DateTime_UTC": "Tue, 08 Jul 2025 08:53:23 +0200",
    "frameSize_Bytes": 5440000,
    "imageDataSize_Bytes": 5363840000,
    "headerSize_Bytes": 178,
    "filesize_Bytes": 5363848066,
    "tailsize_Bytes": 7888,
    "tailsizePerFrame_Bytes": 8
}

vnp85 avatar Jul 08 '25 13:07 vnp85

Could you please double check the meaning of this line:

https://github.com/melix/astro4j/blob/main/jserfile/src/main/java/me/champeau/a4j/ser/SerFileReader.java#L230

it seems to me that you are dropping significant bits (shifting to the left 8+bits to drop) instead of to the right

vnp85 avatar Jul 08 '25 14:07 vnp85

frameData.getShort() returns a int16_t, signed. I think the culprit is somewhere over there

vnp85 avatar Jul 08 '25 14:07 vnp85

No it's not. The reader is not a fault, it has been tested intensively. If there's an issue, it's with the writer. See the spec at https://grischa-hahn.hier-im-netz.de/astro/ser/

melix avatar Jul 08 '25 14:07 melix

What do you mean by "the writer" -- the way you output these frames, either to the trimmed video and/or fits frames? Or sharpcap? AS4, PIPP etc read these files well.

My C mind really wants to put that getShort into a proper local variable and make sure all the bits are accounted for, and the most significant bit is not somehow shifted into oblivion because reasons, integer promotion or whatnot

vnp85 avatar Jul 08 '25 14:07 vnp85

The code you're looking at is the code which infers the pixel depth, not the code which will decode the bytes (that's why you are in fixReader). It's there to do the same as other SER readers like SER Player do, which is because some software lie on the pixel depth. Decoding happens in decoders like https://github.com/melix/astro4j/blob/518c3ceb844991ec78b3cdb17cd7b6094c96d3f8/jsolex-core/src/main/java/me/champeau/a4j/jsolex/processing/ser/FastImageConverter.java#L95

I'm mentioning the writer because you're saying you have the problem on a trimmed file, and the trimmed file is using a writer of mine, so it has more chances of being faulty, since it's not as intensively tested.

https://github.com/melix/astro4j/blob/e7f8654ab814d9a39d46e9982791cbdac8c809e2/jserfile/src/main/java/me/champeau/a4j/ser/SerFileWriter.java#L34

melix avatar Jul 08 '25 14:07 melix

We've established the problem is also

  • in the frame debugger
  • in the img(nnn) output
Image

The same in AS4

Image

vnp85 avatar Jul 08 '25 14:07 vnp85

IMHO, this symptom is definitely that of losing bits, it could well be the sign bit getting lost somewhere for whatever reason

Your viewer is also a bit (one bit?) brighter, compared to AS4's raw view

vnp85 avatar Jul 08 '25 14:07 vnp85

To better explain what I am talking about, please consider this naive snippet I quickly hacked togehter, where I make one bit get lost, because integer promotion etc moves the sign bit around before shifting:

Image

vnp85 avatar Jul 08 '25 14:07 vnp85

Wait, I thought you told me you had the same issue replaying the trimmed video in SER player. What does the log say wrt to number of bits? Again this could simply be bad sampling, we have to infer the pixel depth...

melix avatar Jul 08 '25 14:07 melix

The trimmed video reflects this issue, but it begins earlier then the trimming. It is there from the very start, I have an idea, let me check it

vnp85 avatar Jul 08 '25 15:07 vnp85

Ok I had misunderstood. Then my educated guess is that it inferred 15 bits instead of 16 in your case (that shows up in the logs as a line like:

Color mode : MONO (2 bytes per pixel, depth = 16 bits)

melix avatar Jul 08 '25 15:07 melix

OK, so you have two different methods to get the same color:

One is here: https://github.com/melix/astro4j/blob/518c3ceb844991ec78b3cdb17cd7b6094c96d3f8/jsolex-core/src/main/java/me/champeau/a4j/jsolex/processing/ser/FastImageConverter.java#L91

And the other one is here https://github.com/melix/astro4j/blob/edac445e0eaa7257be6f15f50770f952db4e411a/jserfile/src/main/java/me/champeau/a4j/ser/SerFileReader.java#L223

Am I missing something?

Image

vnp85 avatar Jul 08 '25 15:07 vnp85

Please look at not a few bits but a byte going missing,

am I missing somehitng?

vnp85 avatar Jul 08 '25 15:07 vnp85

Yes. Inference :) (and the fact there are different decoders, so there's more than 2 versions to read a color, since it also depends on whether it's mono, bayer, ... :D). Welcome to the wonderful world of codecs :)

melix avatar Jul 08 '25 15:07 melix

fucketyfuck, it was there in the log all along

depth = 15 bits

12:06:19.166 [INFO] Output directory set to D:\2025-07-08\Sun-3640_filter-n99--Skywatcher-OtaR62Ap400F-SHG
12:06:19.166 [INFO] File 2025-07-08-0847_0-Sun-3640.ser
12:06:19.230 [INFO] Date 2025-07-08T08:46:44.632850600
12:06:19.231 [INFO] SER file contains 945 frames
12:06:19.231 [INFO] Color mode : MONO (2 bytes per pixel, depth = 15 bits)
12:06:19.231 [INFO] Width: 3400, height: 800
12:06:19.231 [INFO] Solar parameters Carrington rotation = 2299, B0 = 3.66°, L0 = 110.48°, P = 0.74°
12:06:19.231 [INFO] Computing average image and detecting limb
12:06:44.107 [INFO] Dimensions of raw image determined : 3400x945
12:06:44.108 [INFO] Processing will require approximatively 275.77MB of disk space
12:06:45.623 [INFO] Detected spectral line Sodium (D1) (5895.92Å) with binning 1 (for pixel size 2.00µm)
12:06:45.623 [INFO] Starting reconstruction...
12:06:45.623 [INFO] Distortion polynomial ax3 + bx2 + cx + d = 0
   - a = 0.0
   - b = 7.033106896505656E-6
   - c = 0.0013451866444161695
   - d = 221.69989718673153
12:06:45.623 [INFO] Memory pressure factor 3
12:06:45.623 [INFO] Processing batch 1
12:06:53.730 [INFO] Reconstruction performance: 613.2 MB/s
12:06:53.830 [INFO] Global reconstruction performance: 597.4 MB/s
12:06:53.830 [INFO] Reconstruction done. Generating images...
12:06:59.219 [INFO] Black estimate 356.08
12:06:59.307 [INFO] Detected X/Y ratio: 0.16
12:06:59.965 [INFO] Diameter 2931.20
12:07:03.122 [INFO] Dimensions of geometry corrected image determined : 4400x4400

vnp85 avatar Jul 08 '25 15:07 vnp85

So, the reader picks up a random number of frames, some at the beginning, some at the middle, etc to figure out the max value and pixel depth. Let me guess, in your video, you have very large black regions?

melix avatar Jul 08 '25 15:07 melix

Anyway, my intuition is that the sign bit, in some type inference, integer promotion, goes missing

Another idea: why do you go

var dataLen = width * height * numPlanes;

            for (int j = 0; j < dataLen; j += 16) {

why do you jump by 16 here? You'd not process the entire frame

vnp85 avatar Jul 08 '25 15:07 vnp85

because we want the inference to not slow down processing too much. This is already the reason why when you select a large file it takes sometimes several seconds before showing that it's going to process it.

melix avatar Jul 08 '25 15:07 melix