Skip to content

Commit

Permalink
Finish squashing some more bugs. This one should be 2.11.0 release.
Browse files Browse the repository at this point in the history
  • Loading branch information
ssilburn committed Aug 1, 2023
1 parent fc47a04 commit 267e8c7
Show file tree
Hide file tree
Showing 6 changed files with 24 additions and 34 deletions.
5 changes: 4 additions & 1 deletion CHANGELOG.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ New & Enhancements:
* Improved performance of generating field of view representations and mapping camera images to CAD surface.
* Improved behaviour of "Set CAD view to match fit" button when using images with multiple sub-views in the fitting calibration tool.
* Added basic documentation of file formats.

* Improved image enhancement for some images where it previously had little effect

Compatibility:
* Move to new style packaging with pyproject.toml for compatibility with pip > 23. This means less flexible dependency management, but the dependencies are readily available enough now that this should be OK. (#83, #100)
Expand All @@ -37,6 +37,9 @@ Fixes:
* Fixed some typos / wording issues in GUI
* Switch from using 32bit int to 32bit float for saving pixel coordinates and binning values in Raycast NetCDF files, to allow correct saving & loading of raycasting witj sub-pixel sampling.
* Fixed bug in detection of monochrome images in enhance_image.scale_to_8bit()
* Fixed a bug in Calibration.set_detector_window() when using a detector window not completely overlapping the originally calibrated one.
* Fixed a bug which could raise exceptions in the image analyser if using a detector sub-window and movement correction.
* Removed some RuntimeWarnings raised by enhance_image() for some images.


Minor Release 2.10.0 (November 2022)
Expand Down
10 changes: 3 additions & 7 deletions calcam/cadmodel.py
Original file line number Diff line number Diff line change
Expand Up @@ -584,9 +584,6 @@ def build_octree(self):

if self.cell_locator is None:

if self.status_callback is not None:
self.status_callback('Building CAD model octree...')

appender = vtk.vtkAppendPolyData()

for fname in self.get_enabled_features():
Expand All @@ -607,7 +604,6 @@ def build_octree(self):
self.raycast_args = (vtk.mutable(0), np.zeros(3), np.zeros(3), vtk.mutable(0), vtk.mutable(0), vtk.vtkGenericCell())



def intersect_with_line(self,line_start,line_end,surface_normal=False):
"""
Find the first intersection of a straight line segment with the CAD geometry, if one
Expand All @@ -623,10 +619,10 @@ def intersect_with_line(self,line_start,line_end,surface_normal=False):
Returns:
Multiple return values:
- bool : Whether or not the line segment intersects the CAD geometry
- np.array : 3-element NumPy array with x,y,z position of the intersection. If there is \
- bool : Whether or not the line segment intersects the CAD geometry
- np.array : 3-element NumPy array with x,y,z position of the intersection. If there is \
no intersection, `line_end` is returned.
- np.array or None : Only returned if surface_normal = True; the surface normal at the intersection. \
- np.array or None : Only returned if surface_normal = True; the surface normal at the intersection. \
If there is no intersection, returns `None`.
"""
Expand Down
27 changes: 6 additions & 21 deletions calcam/calibration.py
Original file line number Diff line number Diff line change
Expand Up @@ -573,17 +573,10 @@ def set_detector_window(self,window,bounds_error='warn'):
elif bounds_error.lower() == 'warn':
warnings.warn('Requested calibration crop of {:d}x{:d} at offset {:d}x{:d} exceeds the bounds of the original calibration ({:d}x{:d} at offset {:d}x{:d}). All pixels outside the originally calibrated area will be assumed to contain no image.'.format(window[2],window[3],window[0],window[1],self.geometry.x_pixels,self.geometry.y_pixels,self.geometry.offset[0],self.geometry.offset[1]))

new_subview_mask = np.zeros((window[3],window[2]),dtype=np.int8) - 1
padded_subview_mask = np.zeros((max(self.geometry.offset[1] + orig_shape[1],window[1]+window[3]),max(self.geometry.offset[0] + orig_shape[0],window[0]+window[2])),dtype=np.int8) - 1
padded_subview_mask[self.geometry.offset[1]:self.geometry.offset[1]+orig_shape[1],self.geometry.offset[0]:self.geometry.offset[0]+orig_shape[0]] = self.native_subview_mask[:,:]

xstart_newmask = max(0,self.geometry.offset[0] - window[0])
ystart_newmask = max(0,self.geometry.offset[1] - window[1])

xstart_oldmask = max(0,window[0] - self.geometry.offset[0])
ystart_oldmask = max(0,window[1] - self.geometry.offset[1])
w = min(orig_shape[0] - xstart_oldmask,window[2] - xstart_newmask)
h = min(orig_shape[1] - ystart_oldmask,window[3] - ystart_newmask)

new_subview_mask[ystart_newmask:ystart_newmask+h,xstart_newmask:xstart_newmask+w] = orig_subview_mask[ystart_oldmask:ystart_oldmask+h,xstart_oldmask:xstart_oldmask+w]
new_subview_mask = padded_subview_mask[window[1]:window[1]+window[3],window[0]:window[0]+window[2]]

else:
new_subview_mask = orig_subview_mask[window[1] - self.geometry.offset[1]:window[1] - self.geometry.offset[1] + window[3],window[0] - self.geometry.offset[0]:window[0] - self.geometry.offset[0] + window[2]]
Expand All @@ -610,16 +603,9 @@ def set_detector_window(self,window,bounds_error='warn'):
# Case where the requested crop has parts outside the original image
if window[0] < self.geometry.offset[0] or window[1] < self.geometry.offset[1] or window[0] + window[2] > self.geometry.offset[0] + orig_shape[0] or window[1] + window[3] > self.geometry.offset[1] + orig_shape[1]:

xstart_newim = max(0,self.geometry.offset[0] - window[0])
ystart_newim = max(0,self.geometry.offset[1] - window[1])

xstart_oldim = max(0,window[0] - self.geometry.offset[0])
ystart_oldim = max(0,window[1] - self.geometry.offset[1])
w = min(orig_shape[0] - xstart_oldim,window[2] - xstart_newim)
h = min(orig_shape[1] - ystart_oldim,window[3] - ystart_newim)

self.image = np.zeros((window[3],window[2],self.native_image.shape[2]),dtype=self.native_image.dtype)
self.image[ystart_newim:ystart_newim+h,xstart_newim:xstart_newim+w,:] = self.native_image[ystart_oldim:ystart_oldim+h,xstart_oldim:xstart_oldim+w,:]
padded_im = np.zeros((max(self.geometry.offset[1] + orig_shape[1],window[1]+window[3]),max(self.geometry.offset[0] + orig_shape[0],window[0]+window[2]),self.native_image.shape[2]),self.native_image.dtype)
padded_im[self.geometry.offset[1]:self.geometry.offset[1]+orig_shape[1],self.geometry.offset[0]:self.geometry.offset[0]+orig_shape[0],:] = self.native_image[:,:,:]
self.image = padded_im[window[1]:window[1]+window[3],window[0]:window[0]+window[2]]

else:
# Simply crop the original
Expand Down Expand Up @@ -1128,7 +1114,6 @@ def subview_lookup(self,x,y,coords='Display'):


good_mask = (x >= -0.5) & (y >= -0.5) & (x < shape[0] - 0.5) & (y < shape[1] - 0.5)

try:
x[ good_mask == 0 ] = 0
y[ good_mask == 0 ] = 0
Expand Down
4 changes: 2 additions & 2 deletions calcam/gui/image_analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -425,12 +425,12 @@ def update_from_2d(self,coords_2d):

for i,coords in enumerate(coords_2d):
if coords is not None:
if self.mov_correction is not None:
coords = self.mov_correction.moved_to_ref_coords(*coords)

if self.calibration.subview_lookup(*coords) == -1:
raise UserWarning('The clicked position is outside the calibrated field of view.')
elif np.any(coords != self.coords_2d[i]):
if self.mov_correction is not None:
coords = self.mov_correction.moved_to_ref_coords(*coords)
raydata = raycast_sightlines(self.calibration,self.cadmodel,coords[0],coords[1],coords='Display',verbose=False)
self.update_from_3d(raydata.ray_end_coords[0,:])
break
Expand Down
10 changes: 8 additions & 2 deletions calcam/image_enhancement.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,8 @@ def enhance_image(image,target_msb=25,target_noise=500,tiles=(20,20),downsample=
best_cliplim = np.polyval(coefs,target_msb)
if best_cliplim > 0:
result = cv2.createCLAHE(best_cliplim, tiles).apply(image)

else:
result = cv2.createCLAHE(1, tiles).apply(image)

if bilateral:
result = cv2.bilateralFilter(result,d=-1,sigmaColor=25,sigmaSpace=25)
Expand Down Expand Up @@ -180,7 +181,12 @@ def local_contrast(image,tilegridsize=(20,20)):

for i in range(tilegridsize[1]):
for j in range(tilegridsize[0]):
sb.append(image[i*tile_height:(i+1)*tile_height,j*tile_width:(j+1)*tile_width].std())
sample = image[i*tile_height:(i+1)*tile_height,j*tile_width:(j+1)*tile_width]
if len(np.unique(sample)) > 1:
sb.append(sample.std())

if len(sb) == 0:
sb = [0]

return np.nanmean(sb)

Expand Down
2 changes: 1 addition & 1 deletion calcam/raycast.py
Original file line number Diff line number Diff line change
Expand Up @@ -200,8 +200,8 @@ def raycast_sightlines(calibration,cadmodel,x=None,y=None,exclusion_radius=0.0,b
raystart = results.ray_start_coords[ind] + exclusion_radius * LOSDir[ind]
rayend = results.ray_start_coords[ind] + max_ray_length * LOSDir[ind]

#retval = cell_locator.IntersectWithLine(raystart,rayend,1.e-6,t,pos,coords_,subid,cellid,cell)
ret_vals = cadmodel.intersect_with_line(raystart,rayend,calc_normals)

if ret_vals[0]:
results.ray_end_coords[ind,:] = ret_vals[1][:]
if calc_normals:
Expand Down

0 comments on commit 267e8c7

Please sign in to comment.