Commit 582761bd authored by JosefBrandt's avatar JosefBrandt

Modularization of analysisview, DocStrings

parent 07883df1
......@@ -10,3 +10,5 @@ analysis/database_config\.txt
*.c
external/build/
.idea/
......@@ -135,7 +135,7 @@ class GEPARDMainWindow(QtWidgets.QMainWindow):
self.openAct.setShortcut("Ctrl+O")
self.openAct.triggered.connect(self.open)
self.importAct = QtWidgets.QAction("&Import Project...", self)
self.importAct = QtWidgets.QAction("&Import Zeiss Project...", self)
self.importAct.setShortcut("Ctrl+I")
self.importAct.triggered.connect(self.importProject)
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -28,6 +28,7 @@ from .particleClassification.colorClassification import ColorClassifier
from .particleClassification.shapeClassification import ShapeClassifier
from ..segmentation import closeHolesOfSubImage
from ..errors import InvalidParticleError
from ..helperfunctions import cv2imread_fix
class ParticleStats(object):
longSize = None
......@@ -45,7 +46,25 @@ def particleIsValid(particle):
return False
return True
def getParticleStatsWithPixelScale(contour, fullimage, dataset):
def updateStatsOfParticlesIfNotManuallyEdited(particleContainer):
dataset = particleContainer.datasetParent
fullimage = loadFullimageFromDataset(dataset)
zimg = loadZValImageFromDataset(dataset)
for particle in particleContainer.particles:
if not hasattr(particle, "wasManuallyEdited"):
particle.wasManuallyEdited = False
if not particle.wasManuallyEdited:
newStats = getParticleStatsWithPixelScale(particle.contour, dataset, fullimage, zimg)
particle.__dict__.update(newStats.__dict__)
def getParticleStatsWithPixelScale(contour, dataset, fullimage=None, zimg=None):
if fullimage is None:
fullimage = loadFullimageFromDataset(dataset)
if zimg is None:
zimg = loadZValImageFromDataset(dataset)
cnt = deepcopy(contour)
pixelscale = dataset.getPixelScale()
......@@ -58,7 +77,7 @@ def getParticleStatsWithPixelScale(contour, fullimage, dataset):
if 0 in [newStats.longSize, newStats.shortSize, newStats.area]:
raise InvalidParticleError
newStats.height = getParticleHeight(cnt, dataset)
newStats.height = getParticleHeight(cnt, zimg, dataset)
newStats.shape = getParticleShape(cnt, newStats.height)
if newStats.shape == 'fibre':
newStats.longSize, newStats.shortSize = getFibreDimension(cnt)
......@@ -90,8 +109,8 @@ def getParticleShape(contour, particleHeight, shapeClassifier=None):
shape = shapeClassifier.classifyShape(contour, particleHeight)
return shape
def getParticleHeight(contour, dataset):
zimg = getParticleImageFromFullimage(contour, dataset.getZvalImg())
def getParticleHeight(contour, fullZimg, dataset):
zimg = getParticleImageFromFullimage(contour, fullZimg)
if zimg.shape[0] == 0 or zimg.shape[1] == 0:
raise InvalidParticleError
......@@ -218,3 +237,9 @@ def getParticleCenterPoint(contour):
x += xmin
y += ymin
return x, y
def loadFullimageFromDataset(dataset):
return cv2imread_fix(dataset.getImageName(), cv2.COLOR_BGR2RGB)
def loadZValImageFromDataset(dataset):
return cv2imread_fix(dataset.getZvalImageName(), cv2.IMREAD_GRAYSCALE)
\ No newline at end of file
......@@ -22,12 +22,12 @@ If not, see <https://www.gnu.org/licenses/>.
class ColorClassifier(object):
def __init__(self):
hue_tolerance = 50
self.colors = [ColorRangeHSV('yellow', 30, hue_tolerance, 40, 255),
ColorRangeHSV('blue', 120, hue_tolerance, 40, 255),
ColorRangeHSV('red', 180, hue_tolerance, 40, 255),
ColorRangeHSV('red', 0, hue_tolerance, 40, 255),
ColorRangeHSV('green', 70, hue_tolerance, 40, 255),
hue_tolerance = 40
self.colors = [ColorRangeHSV('yellow', 30, hue_tolerance, 80, 255),
ColorRangeHSV('blue', 120, hue_tolerance, 80, 255),
ColorRangeHSV('red', 180, hue_tolerance, 60, 255),
ColorRangeHSV('red', 0, hue_tolerance, 60, 255),
ColorRangeHSV('green', 70, hue_tolerance, 60, 255),
ColorRangeHSV('white', 128, 256, 0, 40)]
def classifyColor(self, meanHSV):
......
......@@ -26,7 +26,6 @@ from PyQt5 import QtWidgets
from . import importSpectra
from .particleAndMeasurement import Particle, Measurement
class ParticleContainer(object):
def __init__(self, datasetParent):
super(ParticleContainer, self).__init__()
......@@ -34,8 +33,6 @@ class ParticleContainer(object):
self.particles = []
self.measurements = []
self.inconsistentParticles = []
self.typeHistogram = None
def addEmptyMeasurement(self):
newMeas = Measurement()
......@@ -173,6 +170,13 @@ class ParticleContainer(object):
contours.append(particle.contour)
return contours
def getIndicesOfColoredNotUnknownParticles(self):
coloredParticleIndices = []
for particle in self.particles:
if particle.getParticleAssignment() != 'unknown' and particle.color not in ['white', 'non-determinable']:
coloredParticleIndices.append(particle.index)
return coloredParticleIndices
def getParticleAssignmentByIndex(self, partIndex):
particle = self.getParticleOfIndex(partIndex)
return particle.getParticleAssignment()
......
......@@ -230,7 +230,7 @@ class ParticleEditor(QtCore.QObject):
self.particlePainter = None
def mergeParticlesInParticleContainerAndSampleView(self, indices, newContour, assignment):
stats = pc.getParticleStatsWithPixelScale(newContour, self.viewparent.imgdata, self.viewparent.dataset)
stats = pc.getParticleStatsWithPixelScale(newContour, self.viewparent.dataset, fullimage=self.viewparent.imgdata)
self.viewparent.addParticleContourToIndex(newContour, len(self.viewparent.contourItems)-1)
self.particleContainer.addMergedParticle(indices, newContour, stats, newAssignment=assignment)
......@@ -271,7 +271,7 @@ class ParticleEditor(QtCore.QObject):
self.viewparent.dataset.particleContainer.resetParticleIndices()
self.viewparent.resetContourIndices()
self.viewparent.analysiswidget.updateHistogramsAndContours()
self.viewparent.analysiswidget.updatePlotsAndContours()
......
......@@ -31,6 +31,7 @@ import json
import analysis.DBAssignments as dbassignments
from analysis.DBAssignments import DBAssignment
class SQLExport(QtWidgets.QDialog):
def __init__(self, dataset):
super(SQLExport, self).__init__()
......@@ -65,7 +66,8 @@ class SQLExport(QtWidgets.QDialog):
f'server config key {key} is missing databae_config json file'
self.cnx = None
self.createInterface()
if self.config is not None:
self.createInterface()
def createInterface(self):
layout = QtWidgets.QVBoxLayout()
......@@ -354,8 +356,7 @@ class SQLExport(QtWidgets.QDialog):
return True
def connect(self):
if self.config is None:
return
assert self.config is not None
try:
self.cnx = mysql.connector.connect(**self.config) #port: 3306
except mysql.connector.Error as err:
......
......@@ -21,9 +21,7 @@ If not, see <https://www.gnu.org/licenses/>.
import os
import pickle
import numpy as np
import cv2
import sys
from .helperfunctions import cv2imread_fix, cv2imwrite_fix
from copy import copy
from .analysis.particleContainer import ParticleContainer
from .legacyConvert import legacyConversion, currentVersion
......@@ -170,25 +168,13 @@ class DataSet(object):
def getPixelScale(self, mode=None):
if mode is None:
mode = self.imagescanMode
return (self.pixelscale_df if mode == 'df' else self.pixelscale_bf)
def getZvalImg(self):
if self.zvalimg == 'saved':
self.loadZvalImg()
return self.zvalimg
return (self.pixelscale_df if mode == "df" else self.pixelscale_bf)
def saveZvalImg(self):
if self.zvalimg is not None:
cv2imwrite_fix(self.getZvalImageName(), self.zvalimg)
def loadZvalImg(self):
if os.path.exists(self.getZvalImageName()):
self.zvalimg = cv2imread_fix(self.getZvalImageName(), cv2.IMREAD_GRAYSCALE)
if self.zvalimg is None:
print(self.getZvalImageName())
else:
raise FileNotFoundError
self.zvalimg = "saved"
def getZval(self, pixelpos):
assert self.zvalimg is not None
i, j = int(round(pixelpos[1])), int(round(pixelpos[0]))
......
......@@ -158,7 +158,8 @@ def updateParticleStats(dset):
print('particle is invalid and will be deleted!')
deleteIndices.append(particle.index)
fullimage = cv2.cvtColor(cv2imread_fix(dset.getImageName()), cv2.COLOR_BGR2RGB)
fullimage = pc.loadFullimageFromDataset(dset)
zimg = pc.loadZValImageFromDataset(dset)
colorClassifier = pc.ColorClassifier()
shapeClassifier = pc.ShapeClassifier()
deleteIndices = []
......@@ -184,7 +185,7 @@ def updateParticleStats(dset):
particle.color = pc.getParticleColor(particleImg, colorClassifier)
try:
particle.height = pc.getParticleHeight(particle.contour, dset)
particle.height = pc.getParticleHeight(particle.contour, zimg, dset)
particle.shape = pc.getParticleShape(particle.contour, particle.height, shapeClassifier)
except InvalidParticleError:
markForDeletion(particle)
......
......@@ -233,7 +233,7 @@ class RamanScanUI(QtWidgets.QWidget):
self.view.saveDataSet()
self.view.prepareAnalysis()
self.view.scaleImage(2.0)
self.view.zoomDisplay(2.0)
self.view.highLightRamanIndex(0)
self.view.blockUI()
self.group2.setEnabled(False)
......
This diff is collapsed.
......@@ -445,7 +445,7 @@ class Segmentation(object):
if label==0:
continue
try:
stats = getParticleStatsWithPixelScale(cnt, img, dataset)
stats = getParticleStatsWithPixelScale(cnt, dataset, fullimage=img)
except InvalidParticleError:
print('invalid contour in detection, skipping partile. Contour is:', cnt)
continue
......
......@@ -41,6 +41,10 @@ class SegmentationContour(QtWidgets.QGraphicsItem):
self.getBrectAndPolygon()
def getBrectAndPolygon(self):
"""
Calculates the bounding rect (needed for drawing the QGraphicsView) and converts the contourdata to a polygon.
:return:
"""
polygon = QtGui.QPolygonF()
x0 = self.contourData[:,0,0].min()
x1 = self.contourData[:,0,0].max()
......@@ -261,6 +265,7 @@ class ParticleInfo(QtWidgets.QGraphicsItem):
self.entries = {}
self.fontsize = 12
self.spacer = 10
self.pixelOffsetToParticle = 200
self.getEntries()
self.partCenter = getParticleCenterPoint([self.particle.contour])
......@@ -268,11 +273,28 @@ class ParticleInfo(QtWidgets.QGraphicsItem):
self.height = len(self.entries)*(self.fontsize+self.spacer) + self.spacer
self.width = 300
self.brect = QtCore.QRectF()
self.getBrect()
def boundingRect(self):
return QtCore.QRectF(-self.width/2, -self.height/2 , self.width+200, self.height+200)
return self.brect
def getBrect(self):
"""
Calculate the bounding rect, which is needed for displaying the QGraphicsItem.
:return:
"""
top = -self.height/2
left = -self.width/2
width = self.width + self.pixelOffsetToParticle
height = self.height + self.pixelOffsetToParticle
self.brect = QtCore.QRectF(left, top , width, height)
def getEntries(self):
"""
Reads particle propertes and copies them to own dictionary
:return:
"""
self.entries['Assignment:'] = self.particle.getParticleAssignment()
self.entries['Long Size (µm):'] = int(round(self.particle.longSize))
self.entries['Short Size (µm):'] = int(round(self.particle.shortSize))
......@@ -282,8 +304,12 @@ class ParticleInfo(QtWidgets.QGraphicsItem):
self.entries['Numbers of Spectra:'] = len(self.particle.getMeasurementIndices())
def setToAdequatePosition(self):
x = self.partCenter[0] - 200
y = self.partCenter[1] - 200
"""
Sets the pounding box relative to the thickest position in the particle.
:return:
"""
x = self.partCenter[0] - self.pixelOffsetToParticle
y = self.partCenter[1] - self.pixelOffsetToParticle
self.setPos(x, y)
def paint(self, painter, option, widget):
......
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