11# -*- coding: utf-8 -*-
2+
3+ from __future__ import annotations
4+
25import sys
36import weakref
7+ from typing import TYPE_CHECKING
48
59import numpy as np
610from qtpy import QtCore as QC
1216from plotpy .items .image .misc import get_image_from_qrect
1317from plotpy .mathutils .geometry import rotate , translate , vector_angle , vector_norm
1418
19+ if TYPE_CHECKING :
20+ from plotpy .items import AnnotatedObliqueRectangle , AnnotatedSegment
21+
1522try :
1623 from plotpy ._scaler import INTERP_LINEAR , _scale_tr
1724except ImportError :
@@ -434,14 +441,8 @@ class ObliqueCrossSectionItem(CrossSectionItem):
434441
435442 DEBUG = False
436443
437- def __init__ (self , curveparam = None , errorbarparam = None ):
438- CrossSectionItem .__init__ (self , curveparam , errorbarparam )
439-
440- def update_curve_data (self , obj ):
441- """
442-
443- :param obj:
444- """
444+ def update_curve_data (self , obj : AnnotatedObliqueRectangle ) -> None :
445+ """Update curve data"""
445446 source = self .get_source_image ()
446447 rect = obj .get_bounding_rect_coords ()
447448 if rect is not None and source .data is not None :
@@ -455,3 +456,51 @@ def update_curve_data(self, obj):
455456 def update_scale (self ):
456457 """ """
457458 pass
459+
460+
461+ def compute_line_section (
462+ data : np .ndarray , row0 , col0 , row1 , col1
463+ ) -> tuple [np .ndarray , np .ndarray ]:
464+ """Return intensity profile of data along a line
465+
466+ Args:
467+ data: 2D array
468+ row0, col0: start point
469+ row1, col1: end point
470+ """
471+ # Keep coordinates inside the image
472+ row0 = max (0 , min (row0 , data .shape [0 ] - 1 ))
473+ col0 = max (0 , min (col0 , data .shape [1 ] - 1 ))
474+ row1 = max (0 , min (row1 , data .shape [0 ] - 1 ))
475+ col1 = max (0 , min (col1 , data .shape [1 ] - 1 ))
476+ # Keep coordinates in the right order
477+ row0 , row1 = min (row0 , row1 ), max (row0 , row1 )
478+ col0 , col1 = min (col0 , col1 ), max (col0 , col1 )
479+ # Extract the line
480+ line = np .zeros ((2 , max (abs (row1 - row0 ), abs (col1 - col0 )) + 1 ), dtype = np .float64 )
481+ line [0 , :] = np .linspace (row0 , row1 , line .shape [1 ])
482+ line [1 , :] = np .linspace (col0 , col1 , line .shape [1 ])
483+ # Interpolate the line
484+ return line [1 , :], np .array ([data [int (r ), int (c )] for r , c in line .T ])
485+
486+
487+ # Line cross section item
488+ class LineCrossSectionItem (CrossSectionItem ):
489+ """A Qwt item representing line cross section data"""
490+
491+ def update_curve_data (self , obj : AnnotatedSegment ) -> None :
492+ """Update curve data"""
493+ source = self .get_source_image ()
494+ rect = obj .get_rect ()
495+ if rect is not None and source .data is not None :
496+ x0 , y0 , x1 , y1 = obj .get_rect ()
497+ c0 , r0 = source .get_closest_pixel_indexes (x0 , y0 )
498+ c1 , r1 = source .get_closest_pixel_indexes (x1 , y1 )
499+ sectx , secty = compute_line_section (source .data , r0 , c0 , r1 , c1 )
500+ if secty .size == 0 or np .all (np .isnan (secty )):
501+ sectx , secty = np .array ([]), np .array ([])
502+ self .process_curve_data (sectx , secty , None , None )
503+
504+ def update_scale (self ):
505+ """ """
506+ pass
0 commit comments