Skip to content

Commit

Permalink
[api][desktop]: Fix image load in looping
Browse files Browse the repository at this point in the history
  • Loading branch information
tiagohm committed Apr 19, 2024
1 parent df2407a commit 375c622
Show file tree
Hide file tree
Showing 7 changed files with 7 additions and 132 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import nebulosa.image.Image
import nebulosa.image.algorithms.transformation.correction.BiasSubtraction
import nebulosa.image.algorithms.transformation.correction.DarkSubtraction
import nebulosa.image.algorithms.transformation.correction.FlatCorrection
import nebulosa.image.format.Header
import nebulosa.image.format.ImageHdu
import nebulosa.image.format.ReadableHeader
import nebulosa.indi.device.camera.FrameType
Expand Down Expand Up @@ -37,10 +36,9 @@ class CalibrationFrameService(

if (darkFrame != null || biasFrame != null || flatFrame != null) {
var transformedImage = if (createNew) image.clone() else image
var calibrationImage = Image(transformedImage.width, transformedImage.height, Header.Empty, transformedImage.mono)

if (biasFrame != null) {
calibrationImage = biasFrame.path!!.fits().use(calibrationImage::load)!!
val calibrationImage = biasFrame.path!!.fits().use(Image::open)
transformedImage = transformedImage.transform(BiasSubtraction(calibrationImage))
LOG.info("bias frame subtraction applied. frame={}", biasFrame)
} else {
Expand All @@ -51,7 +49,7 @@ class CalibrationFrameService(
}

if (darkFrame != null) {
calibrationImage = darkFrame.path!!.fits().use(calibrationImage::load)!!
val calibrationImage = darkFrame.path!!.fits().use(Image::open)
transformedImage = transformedImage.transform(DarkSubtraction(calibrationImage))
LOG.info("dark frame subtraction applied. frame={}", darkFrame)
} else {
Expand All @@ -62,7 +60,7 @@ class CalibrationFrameService(
}

if (flatFrame != null) {
calibrationImage = flatFrame.path!!.fits().use(calibrationImage::load)!!
val calibrationImage = flatFrame.path!!.fits().use(Image::open)
transformedImage = transformedImage.transform(FlatCorrection(calibrationImage))
LOG.info("flat frame correction applied. frame={}", flatFrame)
} else {
Expand Down
2 changes: 1 addition & 1 deletion api/src/main/kotlin/nebulosa/api/image/ImageBucket.kt
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class ImageBucket {
else -> throw IllegalArgumentException("invalid extension: $path")
}

val image = representation.use { openedImage?.first?.load(it) ?: Image.open(it, debayer) }
val image = representation.use { Image.open(it, debayer) }
put(path, image, solution)
return image
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,8 @@ data class FlatWizardStep(
if (!stopped && saved != null) {
val (imageRepresentation, savedPath) = saved!!

image = if (imageRepresentation != null) image?.load(imageRepresentation) ?: Image.open(imageRepresentation, false)
else savedPath.fits().use { image?.load(it) ?: Image.open(it, false) }
image = if (imageRepresentation != null) Image.open(imageRepresentation, false)
else savedPath.fits().use { Image.open(it, false) }

imageBucket?.put(savedPath, image!!)

Expand Down
2 changes: 1 addition & 1 deletion desktop/src/app/image/image.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,7 @@ export class ImageComponent implements AfterViewInit, OnDestroy {

electron.on('CAMERA.CAPTURE_ELAPSED', async (event) => {
if (event.state === 'EXPOSURE_FINISHED' && event.camera.id === this.imageData.camera?.id) {
await this.closeImage(event.savePath !== this.imageData.path)
await this.closeImage(true)

ngZone.run(() => {
this.imageData.path = event.savePath
Expand Down
77 changes: 0 additions & 77 deletions nebulosa-image/src/main/kotlin/nebulosa/image/Image.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ import nebulosa.image.format.*
import okio.Sink
import java.awt.color.ColorSpace
import java.awt.image.*
import kotlin.math.max
import kotlin.math.min

@Suppress("NOTHING_TO_INLINE")
class Image internal constructor(
Expand Down Expand Up @@ -215,28 +213,6 @@ class Image internal constructor(
return image
}

fun canLoad(hdu: ImageHdu): Boolean {
return hdu.width == width && hdu.height == height && hdu.isMono == mono
}

fun canLoad(image: ImageRepresentation): Boolean {
return canLoad(image.filterIsInstance<ImageHdu>().first())
}

fun load(image: ImageRepresentation): Image? {
return load(image.filterIsInstance<ImageHdu>().first())
}

fun load(image: Image): Image? {
return load(image.hdu)
}

fun load(hdu: ImageHdu): Image? {
if (!canLoad(hdu)) return null
load(this, hdu, false)
return this
}

public override fun clone() = if (mono) mono() else color()

fun transform(vararg algorithms: TransformAlgorithm) = algorithms.transform(this)
Expand Down Expand Up @@ -291,59 +267,6 @@ class Image internal constructor(
}
}

@JvmStatic
private fun load(image: Image, hdu: ImageHdu, debayer: Boolean) {
hdu.data.readChannelTo(ImageChannel.RED, image.red)

if (!image.mono) {
if (debayer) {
image.debayer()
} else {
hdu.data.readChannelTo(ImageChannel.GREEN, image.green)
hdu.data.readChannelTo(ImageChannel.BLUE, image.blue)
}
}
}

@JvmStatic
private fun load(image: Image, debayer: Boolean) {
fun rescaling() {
for (p in 0 until image.numberOfChannels) {
val minMax = floatArrayOf(Float.MAX_VALUE, Float.MIN_VALUE)
val plane = image.data[p]

for (i in plane.indices) {
val k = plane[i]
minMax[0] = min(minMax[0], k)
minMax[1] = max(minMax[1], k)
}

if (minMax[0] < 0f || minMax[1] > 1f) {
val k = minMax[1] - minMax[0]

for (i in plane.indices) {
plane[i] = (plane[i] - minMax[0]) / k
}
}
}
}

// TODO: DATA[i] = BZERO + BSCALE * DATA[i]

// Mono.
if (image.mono) {
rescaling()
} else {
val bayer = CfaPattern.from(image.header)

if (debayer && bayer != null) {
Debayer(bayer).transform(image)
}

rescaling()
}
}

@JvmStatic
fun open(bufferedImage: BufferedImage): Image {
val header = FitsHeader()
Expand Down
23 changes: 0 additions & 23 deletions nebulosa-image/src/test/kotlin/FitsTransformAlgorithmTest.kt
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import io.kotest.matchers.booleans.shouldBeFalse
import io.kotest.matchers.booleans.shouldBeTrue
import io.kotest.matchers.ints.shouldBeExactly
import io.kotest.matchers.nulls.shouldBeNull
import io.kotest.matchers.nulls.shouldNotBeNull
import io.kotest.matchers.shouldBe
import nebulosa.fits.fits
import nebulosa.image.Image
Expand Down Expand Up @@ -121,15 +119,6 @@ class FitsTransformAlgorithmTest : AbstractFitsAndXisfTest() {
mImage.transform(AutoScreenTransformFunction)
mImage.save("fits-mono-auto-stf").second shouldBe "e17cfc29c3b343409cd8617b6913330e"
}
"!mono:reload" {
val mImage0 = Image.open(NGC3344_MONO_8_FITS.fits())

val mImage1 = Image.open(NGC3344_MONO_8_FITS.fits())
mImage1.transform(Invert)

mImage0.load(mImage1.hdu)
mImage0.save("fits-mono-reload").second shouldBe "6e94463bb5b9561de1f0ee0a154db53e"
}
"color:raw" {
val mImage = Image.open(NGC3344_COLOR_32_FITS.fits())
mImage.save("fits-color-raw").second shouldBe "18fb83e240bc7a4cbafbc1aba2741db6"
Expand Down Expand Up @@ -287,17 +276,5 @@ class FitsTransformAlgorithmTest : AbstractFitsAndXisfTest() {
val nImage = mImage.transform(AutoScreenTransformFunction)
nImage.save("fits-color-no-debayer").second shouldBe "958ccea020deec1f0c075042a9ba37c3"
}
"color:reload" {
val mImage0 = Image.open(NGC3344_COLOR_32_FITS.fits())
var mImage1 = Image.open(DEBAYER_FITS.fits())

mImage1.load(mImage0.hdu).shouldNotBeNull()
mImage1.save("fits-color-reload").second shouldBe "18fb83e240bc7a4cbafbc1aba2741db6"

mImage1 = Image.open(DEBAYER_FITS.fits(), false)

mImage1.load(mImage0.hdu).shouldBeNull()
mImage0.load(mImage1.hdu).shouldBeNull()
}
}
}
23 changes: 0 additions & 23 deletions nebulosa-image/src/test/kotlin/XisfTransformAlgorithmTest.kt
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import io.kotest.matchers.booleans.shouldBeFalse
import io.kotest.matchers.booleans.shouldBeTrue
import io.kotest.matchers.ints.shouldBeExactly
import io.kotest.matchers.nulls.shouldBeNull
import io.kotest.matchers.nulls.shouldNotBeNull
import io.kotest.matchers.shouldBe
import nebulosa.image.Image
import nebulosa.image.algorithms.transformation.*
Expand Down Expand Up @@ -121,15 +119,6 @@ class XisfTransformAlgorithmTest : AbstractFitsAndXisfTest() {
mImage.transform(AutoScreenTransformFunction)
mImage.save("xisf-mono-auto-stf").second shouldBe "9204a71df3770e8fe5ca49e3420eed72"
}
"!mono:reload" {
val mImage0 = Image.open(M82_MONO_8_XISF.xisf())

val mImage1 = Image.open(M82_MONO_8_XISF.xisf())
mImage1.transform(Invert)

mImage0.load(mImage1.hdu)
mImage0.save("xisf-mono-reload").second shouldBe "6e94463bb5b9561de1f0ee0a154db53e"
}
"color:raw" {
val mImage = Image.open(M82_COLOR_32_XISF.xisf())
mImage.save("xisf-color-raw").second shouldBe "764e326cc5260d81f3761112ad6a1969"
Expand Down Expand Up @@ -287,17 +276,5 @@ class XisfTransformAlgorithmTest : AbstractFitsAndXisfTest() {
val nImage = mImage.transform(AutoScreenTransformFunction)
nImage.save("xisf-color-no-debayer").second shouldBe "958ccea020deec1f0c075042a9ba37c3"
}
"!color:reload" {
val mImage0 = Image.open(M82_COLOR_32_XISF.xisf())
var mImage1 = Image.open(DEBAYER_FITS.xisf())

mImage1.load(mImage0.hdu).shouldNotBeNull()
mImage1.save("xisf-color-reload").second shouldBe "18fb83e240bc7a4cbafbc1aba2741db6"

mImage1 = Image.open(DEBAYER_FITS.xisf(), false)

mImage1.load(mImage0.hdu).shouldBeNull()
mImage0.load(mImage1.hdu).shouldBeNull()
}
}
}

0 comments on commit 375c622

Please sign in to comment.