Commit 4094480f authored by Robert's avatar Robert Committed by Robert Ohmacht

-(autom.) Speichern und Laden von Datensätzen mit Bildpyramide eingefügt

parent d1baa02a
......@@ -124,6 +124,9 @@ class DataSet(object):
self.zpositions = [] # z-positions for optical scan
self.heightmap = None
self.zvalimg = None
# tiling parameters
self.pyramidParams = None
# parameters specifically for raman scan
self.pshift = None # shift of raman scan position relative to image center
......@@ -169,6 +172,12 @@ class DataSet(object):
def __eq__(self, other):
return recursiveDictCompare(self.__dict__, other.__dict__)
def getPyramidParams(self):
return self.pyramidParams
def setPyramidParams(self, pyramid_params):
self.pyramidParams = pyramid_params
def getPixelScale(self, mode=None):
if mode is None:
......
......@@ -406,7 +406,7 @@ class OpticalScan(QtWidgets.QWidget):
self.dataset = ds
self.points.createWidgets(5, list(zip(ds.fitindices,ds.fitpoints)))
if len(self.dataset.fitindices)>1:
# self.pareaselect.setEnabled(True)
# self.pareaselect.setEnabled(True)
self.areaOptionsGroup.setEnabled(True)
softwarez = self.ramanctrl.getSoftwareZ()
if abs(softwarez) >0.1:
......@@ -467,6 +467,8 @@ class OpticalScan(QtWidgets.QWidget):
dx, dy = (x-p0[0])/width*img.shape[1], (p0[1]-y)/height*img.shape[0]
M = np.float32([[c, s, dx], [-s, c, dy]])
# dst = cv2.warpAffine(img, M, (Nx, Ny))
M_rot = np.float32([[c, s, 0], [-s, c, 0]])
img_rot = cv2.warpAffine(img, M_rot, (img.shape[1], img.shape[0] + 10))
# calc new pixel start coords for tile
......@@ -628,7 +630,7 @@ class OpticalScan(QtWidgets.QWidget):
self.progressbar.setValue(0)
#self.view.imgdata = None
self.pyramid.reset()
self.pyramid.resetScene()
self.view.blockUI()
grid = np.asarray(self.dataset.grid)
......@@ -685,6 +687,7 @@ class OpticalScan(QtWidgets.QWidget):
self.dataqueue.close()
self.dataqueue.join_thread()
self.pyramid.toDataset()
self.pyramid.createFullImage()
if self.deleteImgChecker.isChecked():
......
......@@ -22,6 +22,7 @@ If not, see <https://www.gnu.org/licenses/>.
import os
import cv2
import math
import copy
import numpy as np
from helperfunctions import cv2imread_fix, cv2imwrite_fix
from PIL import Image
......@@ -30,38 +31,56 @@ from PyQt5 import QtCore, QtGui, QtWidgets
class ImagePyramid:
def __init__(self, view: QtWidgets.QGraphicsView):
# tile size
self.tileDim = (1000, 1000)
self.scalingFactor = .5
###
# references to other objects
self.view: QtWidgets.QGraphicsView = view
self.scene = self.view.scene()
self.dataset = None
self.lazyMode = True
#
self.xIdx = 0
self.yIdx = 1
self.currentSlice = 0
self.microscopeMode = None
self.currentTiles = []
self.tileWorkingSets = {}
# params to be saved to dataset
self.datasetParams = [
'preScanModeComplete',
'maxSliceNumber',
'tileDim',
'scalingFactor',
'tileSets',
'fullImageWidth',
'fullImageHeight'
]
self.preScanModeComplete = False
self.maxSliceNumber = 0
self.tileDim = (1000, 1000)
self.scalingFactor = .5
self.tileSets = {}
self.fullImageWidth = 0
self.fullImageHeight = 0
self.tileDimensionList = {}
self.dataset = None
def initDefaults(self):
self.preScanModeComplete = False
self.currentSlice = 0
self.microscopeMode = None
self.srcTiles = []
self.tilePaths = []
self.currentTiles = []
self.tileWorkingSets = {}
self.maxSliceNumber = 0
self.tileDim = (1000, 1000)
self.scalingFactor = .5
self.tileSets = {}
self.fullImageWidth = 0
self.fullImageHeight = 0
self.fullImageCreated = False
self.xIdx = 0
self.yIdx = 1
def onScale(self):
"""
gets called on zoom event in QGraphicsView
:return:
"""
if not self.lazyMode:
if self.preScanModeComplete:
self.updateScene()
def onMove(self):
......@@ -69,11 +88,12 @@ class ImagePyramid:
gets called on scroll event in QGraphicsView
:return:
"""
if not self.lazyMode:
if self.preScanModeComplete:
self.updateScene()
def initScene(self):
self.updateScene()
if self.preScanModeComplete:
self.updateScene()
def updateScene(self):
"""
......@@ -106,9 +126,9 @@ class ImagePyramid:
inv_scaling = (1 / self.scalingFactor) ** self.currentSlice
if self.currentSlice in self.tileDimensionList:
for i in self.tileDimensionList[self.currentSlice]:
for j in self.tileDimensionList[self.currentSlice][i]:
if self.currentSlice in self.tileWorkingSets:
for i in self.tileWorkingSets[self.currentSlice]:
for j in self.tileWorkingSets[self.currentSlice][i]:
# check visibility of view tile
tile_width, tile_height = self.getTileDimensions(i, j)
......@@ -265,10 +285,10 @@ class ImagePyramid:
:return:
"""
s = self.currentSlice if use_slice is None else use_slice
if s in self.tileDimensionList \
and i in self.tileDimensionList[s] \
and j in self.tileDimensionList[s][i]:
return self.tileDimensionList[s][i][j]
if s in self.tileWorkingSets \
and i in self.tileWorkingSets[s] \
and j in self.tileWorkingSets[s][i]:
return self.tileWorkingSets[s][i][j]
return False
......@@ -314,7 +334,7 @@ class ImagePyramid:
:param force:
:return:
"""
rendered = not not self.tileDimensionList[self.currentSlice][i][j]['rendered']
rendered = not not self.tileWorkingSets[self.currentSlice][i][j]['rendered']
if not rendered or force:
if force:
self.removeTile(i, j)
......@@ -339,7 +359,7 @@ class ImagePyramid:
item.setPixmap(pix)
self.scene.addItem(item)
self.currentTiles[len(self.currentTiles):] = [item]
self.tileDimensionList[self.currentSlice][i][j]['rendered'] = item
self.tileWorkingSets[self.currentSlice][i][j]['rendered'] = item
def reset(self):
"""
......@@ -347,24 +367,40 @@ class ImagePyramid:
:return:
"""
self.resetScene()
self.fullImageHeight = 0
self.fullImageWidth = 0
self.initDefaults()
def resetScene(self):
"""
removes all tiles and its references from scene and list of currently rendered tiles
:return:
"""
for s in self.tileDimensionList:
for i in self.tileDimensionList[s]:
for j in self.tileDimensionList[s][i]:
for s in self.tileWorkingSets:
for i in self.tileWorkingSets[s]:
for j in self.tileWorkingSets[s][i]:
self.removeTile(i, j, use_slice=s)
# remove anything that may be left
[self.scene.removeItem(i) for i in self.currentTiles]
self.currentTiles = []
def setDataset(self, dataset):
self.dataset = dataset
def fromDataset(self, dataset=None):
if dataset is not None:
self.dataset = dataset
if self.dataset is not None:
pyramid_params = self.dataset.getPyramidParams()
if pyramid_params is None:
self.reset()
else:
for i in self.datasetParams:
setattr(self, i, pyramid_params[i])
self.tileWorkingSets = copy.deepcopy(self.tileSets)
def toDataset(self):
pyramid_params = {}
for i in self.datasetParams:
pyramid_params[i] = getattr(self, i)
self.dataset.setPyramidParams(pyramid_params)
def setMicroscopeMode(self, microscopemode):
"""
......@@ -430,7 +466,7 @@ class ImagePyramid:
)
item.setPixmap(pix)
if 0 < len(self.currentTiles):
if 0 < len(self.currentTiles) and self.dataset.lastpos is not None:
lp = self.dataset.lastpos
dx, dy = (lp[0] - p[0]) / width * img.shape[1], (p[1] - lp[1]) / height * img.shape[0]
li: QtWidgets.QGraphicsItem = self.currentTiles[-1:][0]
......@@ -452,7 +488,7 @@ class ImagePyramid:
:param fullimgsize:
:return:
"""
self.lazyMode = False
self.preScanModeComplete = True
self.fullImageWidth = current_full_image_width = fullimgsize[self.xIdx]
self.fullImageHeight = current_full_image_height = fullimgsize[self.yIdx]
......@@ -568,12 +604,15 @@ class ImagePyramid:
tile_path = os.path.join(self.dataset.getTilePath(), f"tile_{slice_nr}_{i}_{j}.bmp")
cv2imwrite_fix(tile_path, cv2.cvtColor(img, cv2.COLOR_RGB2BGR))
if slice_nr not in self.tileDimensionList:
self.tileDimensionList[slice_nr] = {}
if i not in self.tileDimensionList[slice_nr]:
self.tileDimensionList[slice_nr][i] = {}
if j not in self.tileDimensionList[slice_nr][i]:
self.tileDimensionList[slice_nr][i][j] = {"dimensions": (img.shape[1], img.shape[0]), "rendered": False}
if slice_nr not in self.tileWorkingSets:
self.tileWorkingSets[slice_nr] = {}
self.tileSets[slice_nr] = {}
if i not in self.tileWorkingSets[slice_nr]:
self.tileWorkingSets[slice_nr][i] = {}
self.tileSets[slice_nr][i] = {}
if j not in self.tileWorkingSets[slice_nr][i]:
self.tileWorkingSets[slice_nr][i][j] = {"dimensions": (img.shape[1], img.shape[0]), "rendered": False}
self.tileSets[slice_nr][i][j] = {"dimensions": (img.shape[1], img.shape[0]), "rendered": False}
def readViewTile(self, slice_nr, i, j):
"""
......@@ -612,8 +651,8 @@ class ImagePyramid:
height = self.fullImageHeight
fullsize_img = Image.new('RGB', (width, height), 'black')
for i in self.tileDimensionList[0]:
for j in self.tileDimensionList[0][i]:
for i in self.tileWorkingSets[0]:
for j in self.tileWorkingSets[0][i]:
timg = Image.fromarray(self.readViewTile(0, i, j))
pos = (i * self.tileDim[self.xIdx], j * self.tileDim[self.yIdx])
fullsize_img.paste(timg, pos)
......
......@@ -69,9 +69,6 @@ class SampleView(QtWidgets.QGraphicsView):
self.ramanSwitchNeeded = True
self.ramanctrl.disconnect()
#self.hScrollBar = self.horizontalScrollBar()
#self.vScrollBar = self.verticalScrollBar()
self.drag = None
self.mode = None
self.dataset = None
......@@ -250,8 +247,10 @@ class SampleView(QtWidgets.QGraphicsView):
self.dataset = loadData(fname)
self.setMicroscopeMode()
self.pyramid.setDataset(self.dataset)
self.pyramid.fromDataset(self.dataset)
self.pyramid.setMicroscopeMode(self.microscopeMode)
self.imparent.setWindowTitle(self.dataset.name + (" SIMULATION" if simulatedRaman else ""))
self.imgdata = None
self.activateMaxMode(loadnew=True)
......@@ -266,11 +265,12 @@ class SampleView(QtWidgets.QGraphicsView):
def new(self, fname):
self.saveDataSet()
# @todo isn't saving twice redundant?
if self.dataset is not None:
self.dataset.save()
self.dataset = DataSet(fname, newProject=True)
self.setMicroscopeMode()
self.pyramid.setDataset(self.dataset)
self.pyramid.fromDataset(self.dataset)
self.pyramid.setMicroscopeMode(self.microscopeMode)
self.imparent.setWindowTitle(self.dataset.name + (" SIMULATION" if simulatedRaman else ""))
self.imgdata = None
......@@ -315,7 +315,7 @@ class SampleView(QtWidgets.QGraphicsView):
return maxmode
def mousePressEvent(self, event):
# if event.button()==QtCore.Qt.RightButton:
# if event.button()==QtCore.Qt.RightButton:
if event.button()==QtCore.Qt.MiddleButton:
self.drag = event.pos()
elif event.button()==QtCore.Qt.LeftButton and self.mode in ["OpticalScan", "RamanScan"] \
......@@ -414,59 +414,43 @@ class SampleView(QtWidgets.QGraphicsView):
def loadPixmap(self, microscope_mode='df'):
self.clearItems()
if self.dataset is None:
#self.addEmptyItem()
#self.item.setPixmap(QtGui.QPixmap())
None
else:
#data = self.imgdata
fname = self.dataset.getImageName()
fpath = self.dataset.getTilePath()
tiles = []
with os.scandir(fpath) as fit:
for entry in fit:
if not entry.name.startswith('.') and entry.is_file():
tiles[len(tiles):] = [entry]
#fname = self.dataset.getImageName()
if self.mode == "ParticleDetection" or self.mode == "ParticleAnalysis":
self.contouritem.resetContours(self.dataset.particlecontours)
#if data is None and os.path.exists(fname):
# data = cv2.cvtColor(cv2imread_fix(fname), cv2.COLOR_BGR2RGB)
# self.imgdata = data
#if data is not None:
# height, width, channel = data.shape
# bytesPerLine = 3 * width
# pix = QtGui.QPixmap()
# pix.convertFromImage(QtGui.QImage(data.data,
# width, height, bytesPerLine, QtGui.QImage.Format_RGB888))
if 0 < len(self.tiles):
for i, tile in enumerate(self.tiles):
'''
img = cv2.cvtColor(cv2imread_fix(tile), cv2.COLOR_BGR2RGB)
item = QtWidgets.QGraphicsPixmapItem()
# @todo get pos
p = self.dataset.grid[i]
item.setPos(p[0], p[1])
item.setAcceptedMouseButtons(QtCore.Qt.NoButton)
height, width, channel = img.shape
bytesPerLine = 3 * width
pix = QtGui.QPixmap()
pix.convertFromImage(
QtGui.QImage(img, width, height, bytesPerLine, QtGui.QImage.Format_RGB888)
)
item.setPixmap(pix)
self.scene().addItem(item)
self.tiles[len(self.tiles):] = [item]
'''
# self.item.setPixmap(pix)
if self.darkenPixmap:
self.scene().setBackgroundBrush(QtGui.QColor(5, 5, 5))
#self.item.setOpacity(0.2)
# self.item.setOpacity(0.2)
else:
self.scene().setBackgroundBrush(QtCore.Qt.darkGray)
#self.item.setOpacity(1)
else:
None
#self.addEmptyItem()
# self.item.setOpacity(1)
#else:
# self.item.setPixmap(QtGui.QPixmap())
if self.mode == "OpticalScan":
for i, p in zip(self.dataset.fitindices, self.dataset.fitpoints):
p = self.dataset.mapToPixel(p, mode=microscope_mode, force=True)
fititem = FitPosIndicator(i+1, pos=p)
self.scene().addItem(fititem)
self.fititems.append(fititem)
self.fititems.append(fititem)
self.pyramid.initScene()
if self.mode == "ParticleDetection" or self.mode == "ParticleAnalysis":
self.prepareAnalysis()
else:
......
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