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

Reference Image handling and self referencing #18

Merged
merged 4 commits into from
Oct 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 57 additions & 13 deletions orangecontrib/snom/preprocess/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@

from Orange.data import Domain
from Orange.preprocess import Preprocess
from orangecontrib.spectroscopy.preprocess import CommonDomain, SelectColumn
from orangecontrib.spectroscopy.preprocess import (
CommonDomain,
SelectColumn,
WrongReferenceException,
)
from orangecontrib.spectroscopy.utils import (
InvalidAxisException,
values_to_linspace,
Expand Down Expand Up @@ -32,21 +36,60 @@ def __call__(self, data):
return np.full(len(data), np.nan)


def _prepare_domain_for_image(data, image_opts):
at = data.domain[image_opts["attr_value"]].copy(compute_value=NoComputeValue())
return domain_with_single_attribute_in_x(at, data.domain)


def _prepare_table_for_image(data, image_opts):
odata = data
domain = _prepare_domain_for_image(data, image_opts)
data = data.transform(domain)
if len(data):
with data.unlocked(data.X):
data.X[:, 0] = odata.get_column(image_opts["attr_value"], copy=True)
return data


def _image_from_table(data, image_opts):
hypercube, _, indices = get_ndim_hyperspec(
data, (image_opts["attr_y"], image_opts["attr_x"])
)
return hypercube[:, :, 0], indices


class PreprocessImageOpts2DOnlyWhole(PreprocessImageOpts):
def __call__(self, data, image_opts):
at = data.domain[image_opts["attr_value"]].copy(compute_value=NoComputeValue())
odata = data
domain = domain_with_single_attribute_in_x(at, data.domain)
data = data.transform(domain)
data = _prepare_table_for_image(data, image_opts)
try:
image, indices = _image_from_table(data, image_opts)
transformed = self.transform_image(image, data)
col = transformed[indices].reshape(-1)
except InvalidAxisException:
col = np.full(len(data), np.nan)
if len(data):
with data.unlocked(data.X):
data.X[:, 0] = odata.get_column(image_opts["attr_value"], copy=True)
data.X[:, 0] = col
return data

def transform_image(self, image, data):
"""
image: a numpy 2D array where image[y,x] is the value in image row y and column x
data: image data set (used for passing meta data)
"""
raise NotImplementedError


class PreprocessImageOpts2DOnlyWholeReference(PreprocessImageOpts):
def __call__(self, data, image_opts):
data = _prepare_table_for_image(data, image_opts)
reference = _prepare_table_for_image(self.reference, image_opts)
try:
hypercube, _, indices = get_ndim_hyperspec(
data, (image_opts["attr_y"], image_opts["attr_x"])
)
image = hypercube[:, :, 0]
transformed = self.transform_image(image, odata)
image, indices = _image_from_table(data, image_opts)
ref_image, _ = _image_from_table(reference, image_opts)
if image.shape != ref_image.shape:
raise WrongReferenceException("Reference data should have length 1")
transformed = self.transform_image(image, ref_image, data)
col = transformed[indices].reshape(-1)
except InvalidAxisException:
col = np.full(len(data), np.nan)
Expand All @@ -55,10 +98,11 @@ def __call__(self, data, image_opts):
data.X[:, 0] = col
return data

def transform_image(self, image, data):
def transform_image(self, image, ref_image, data):
"""
image: a numpy 2D array where image[y,x] is the value in image row y and column x
data: original data set (used for passing meta data)
ref_image: a numpy 2D array where image[y,x] is the value in image row y and column x
data: image data set (used for passing meta data)
"""
raise NotImplementedError

Expand Down
13 changes: 11 additions & 2 deletions orangecontrib/snom/widgets/owpreprocessimage.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

import Orange.data
from Orange import preprocess
from Orange.widgets.widget import Output
from Orange.widgets.widget import Output, Input

from orangecontrib.spectroscopy.widgets.owhyper import BasicImagePlot

Expand Down Expand Up @@ -132,7 +132,16 @@ def progress_interrupt(i: float):
return orig_data, data


class OWPreprocessImage(SpectralImagePreprocess):
class SpectralImagePreprocessReference(SpectralImagePreprocess, openclass=True):
class Inputs(SpectralImagePreprocess.Inputs):
reference = Input("Reference", Orange.data.Table)

@Inputs.reference
def set_reference(self, reference):
self.reference_data = reference


class OWPreprocessImage(SpectralImagePreprocessReference):
name = "Preprocess image"
id = "orangecontrib.snom.widgets.preprocessimage"
description = "Process image"
Expand Down
1 change: 1 addition & 0 deletions orangecontrib/snom/widgets/preprocessors/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@
from orangecontrib.snom.widgets.preprocessors import phase_rotation # noqa: F401
from orangecontrib.snom.widgets.preprocessors import simple_normalize # noqa: F401
from orangecontrib.snom.widgets.preprocessors import linelevel # noqa: F401
from orangecontrib.snom.widgets.preprocessors import self_reference # noqa: F401
72 changes: 72 additions & 0 deletions orangecontrib/snom/widgets/preprocessors/self_reference.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
from AnyQt.QtWidgets import QFormLayout, QLabel

from orangecontrib.spectroscopy.preprocess import MissingReferenceException
from orangecontrib.spectroscopy.widgets.preprocessors.utils import (
BaseEditorOrange,
REFERENCE_DATA_PARAM,
)

from pySNOM.images import SelfReference

from orangecontrib.snom.preprocess.utils import (
PreprocessImageOpts2DOnlyWholeReference,
)
from orangecontrib.snom.widgets.preprocessors.registry import preprocess_image_editors


class SelfRef(PreprocessImageOpts2DOnlyWholeReference):
def __init__(self, reference):
self.reference = reference
if self.reference is None:
raise MissingReferenceException("Self-referencing needs a reference")

def transform_image(self, image, ref_image, data):
d = SelfReference(referencedata=ref_image).transform(image)
return d


class SelfRefEditor(BaseEditorOrange):
name = "Self-referencing"
qualname = "orangecontrib.snom.self_reference"

def __init__(self, parent=None, **kwargs):
super().__init__(parent, **kwargs)

self.reference = None

form = QFormLayout()
self.reference_info = QLabel("Reference data from input!")
form.addRow(self.reference_info)
self.controlArea.setLayout(form)

def activateOptions(self):
pass # actions when user starts changing options

def setParameters(self, params):
self.update_reference_info()

def set_reference_data(self, reference):
self.reference = reference
self.update_reference_info()

def update_reference_info(self):
if not self.reference:
self.reference_info.setText("Reference: missing!")
self.reference_info.setStyleSheet("color: red")
else:
rinfo = "Reference order: N"
self.reference_info.setText(rinfo)
self.reference_info.setStyleSheet("color: black")

@classmethod
def createinstance(cls, params):
params = dict(params)
reference = params.get(REFERENCE_DATA_PARAM, None)
return SelfRef(reference=reference)

def set_preview_data(self, data):
if data:
pass # TODO any settings


preprocess_image_editors.register(SelfRefEditor, 400)
Loading