Commit 5a441838 authored by Robert's avatar Robert Committed by Robert Ohmacht

-fixes tiles not being generated if full image is only slightly bigger than a...

-fixes tiles not being generated if full image is only slightly bigger than a multiple of tile size and scanned images not reaching into all tiles, so full image would not be fully covered by tiles
parent 46a56d63
......@@ -20,9 +20,14 @@ along with this program, see COPYING.
If not, see <https://www.gnu.org/licenses/>.
"""
class InvalidParticleError(Exception):
pass
class NotConnectedContoursError(Exception):
pass
class TileSizeError(Exception):
pass
......@@ -125,6 +125,19 @@ def removeSrcTiles(names, path):
def loadAndPasteImage(srcnames, pyramid, fullzval, width, height,
rotationvalue, p0, p1, p, background=None):
"""
:param list of str srcnames: list of stacked scan files to merge
:param ScenePyramid pyramid: the scene pyramid
:param numpy.ndarray fullzval: full size zval image
:param float width: width of camera
:param float height: height camera
:param float rotationvalue: angle of camera
:param list of float p0: (min x; max y) of scan tile positions
:param list of float p1: (max x; min y) of scan tile positions
:param list of float p: position of current scan tile
:param numpy.ndarray background:
:return:
"""
colimgs = []
for name in srcnames:
curImg = cv2imread_fix(name)
......@@ -680,8 +693,8 @@ class OpticalScan(QtWidgets.QWidget):
self.pyramid.resetScene()
self.view.blockUI()
grid = np.asarray(self.dataset.grid)
p0 = [grid[:,0].min(), grid[:,1].max()]
p1 = [grid[:,0].max(), grid[:,1].min()]
p0 = [grid[:, 0].min(), grid[:, 1].max()]
p1 = [grid[:, 0].max(), grid[:, 1].min()]
self.dataset.lastpos = p0
self.dataset.maxdim = p0 + p1
self.dataset.mode = "opticalscan"
......@@ -698,7 +711,7 @@ class OpticalScan(QtWidgets.QWidget):
except queue.Empty:
i = -1
if i>=0:
if i >= 0:
Ngrid = len(self.dataset.grid)
names = []
......@@ -721,17 +734,17 @@ class OpticalScan(QtWidgets.QWidget):
removeSrcTiles(names, self.dataset.getScanPath())
self.progressbar.setValue(i+1)
if i>3:
if i > 3:
timerunning = time()-self.starttime
ttot = timerunning*Ngrid/(i+1)
time2go = ttot - timerunning
self.progresstime.setText(self.timelabeltext + str(datetime.timedelta(seconds=round(time2go))))
# reload image in sampleview, calls loadPixmap
# not needed anymore as the scene gets manipulated directly via self.pyramid
#self.imageUpdate.emit(self.view.microscopeMode)
# self.imageUpdate.emit(self.view.microscopeMode)
if i==Ngrid-1:
#cv2imwrite_fix(self.dataset.getImageName(), cv2.cvtColor(self.view.imgdata, cv2.COLOR_RGB2BGR))
# cv2imwrite_fix(self.dataset.getImageName(), cv2.cvtColor(self.view.imgdata, cv2.COLOR_RGB2BGR))
self.dataset.saveZvalImg()
self.process.join()
self.dataqueue.close()
......
......@@ -26,6 +26,7 @@ import cv2
import math
import copy
import numpy as np
from .errors import TileSizeError
from .helperfunctions import cv2imread_fix, cv2imwrite_fix
from PIL import Image
from PyQt5 import QtCore, QtGui, QtWidgets
......@@ -439,6 +440,7 @@ class ScenePyramid:
for i in self.datasetParams:
setattr(self, i, pyramid_params[i])
self.tileWorkingSets = copy.deepcopy(self.tileSets)
self.fixMissingTiles()
self.setMicroscopeMode(self.dataset.imagescanMode)
......@@ -448,6 +450,7 @@ class ScenePyramid:
:return:
"""
pyramid_params = {}
self.fixMissingTiles()
for i in self.datasetParams:
pyramid_params[i] = getattr(self, i)
......@@ -625,7 +628,6 @@ class ScenePyramid:
except OSError:
tile = None
if tile is None:
# as full image size might not be divisible by tile dimensions, we have to determine correct tile size
# tile numbering is 0 based
scaling = self.scalingFactor ** slice_nr
......@@ -633,9 +635,19 @@ class ScenePyramid:
fiw = scaling * self.fullImageWidth
fih = scaling * self.fullImageHeight
x = int(math.ceil(max(min(max_x, fiw - i * max_x), 0)))
y = int(math.ceil(max(min(max_y, fih - j * max_y), 0)))
tile = np.zeros((y, x, 3), np.uint8)
tile_w = int(math.ceil(max(min(max_x, fiw - i * max_x), 0)))
tile_h = int(math.ceil(max(min(max_y, fih - j * max_y), 0)))
# tile does exists but its shape is not correct
if tile is not None and (tile_h, tile_w) != tile.shape[:2]:
# this should not happen
raise TileSizeError(
f"tile should have dim ({tile_w}; {tile_h}), but has dim ({tile.shape[1]}; {tile.shape[0]})"
)
# tile does not even exist, create
if tile is None:
tile = np.zeros((tile_h, tile_w, 3), np.uint8)
return tile
def createFullImage(self):
......@@ -860,6 +872,35 @@ class ScenePyramid:
self.opacity = opacity
[tile.setOpacity(opacity) for tile in self.currentTiles]
def fixMissingTiles(self):
"""
:return:
"""
scaling = 1
tile_width, tile_height = self.tileDim
for slice in range(0, self.maxSliceNumber + 1):
img_width = math.ceil(scaling * self.fullImageWidth)
img_height = math.ceil(scaling * self.fullImageHeight)
# tiles in x direction
col_tile_count = math.ceil(img_width / tile_width)
# tiles in y direction
row_tile_count = math.ceil(img_height / tile_height)
for i in range(0, col_tile_count):
w_tile = (tile_width if i + 1 < col_tile_count else img_width % tile_width)
if i not in self.tileSets[slice]:
self.tileSets[slice][i] = {}
self.tileWorkingSets[slice][i] = {}
col = self.tileSets[slice][i]
for j in range(0, row_tile_count):
h_tile = (tile_height if j + 1 < row_tile_count else img_height % tile_height)
if j not in col or col[j]["dimensions"] != (w_tile, h_tile):
tile = self.readViewTile(slice, i, j)
self.saveViewTile(tile, slice, i, j)
scaling *= self.scalingFactor
def destruct(self):
"""
removes all graphics items from scene
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment