Commit 95a7feb0 authored by Josef Brandt's avatar Josef Brandt

BoundingBox approach for overlap detection

parent 0553ff15
......@@ -4,6 +4,7 @@ sys.path.append("C://Users//xbrjos//Desktop//Python")
import gepard
from gepard import dataset
import helpers
import numpy as np
class FilterView(QtWidgets.QGraphicsView):
......@@ -21,8 +22,6 @@ class FilterView(QtWidgets.QGraphicsView):
self.setCacheMode(QtWidgets.QGraphicsView.CacheBackground)
self.setViewportUpdateMode(QtWidgets.QGraphicsView.BoundingRectViewportUpdate)
self.setRenderHint(QtGui.QPainter.Antialiasing)
self.setTransformationAnchor(QtWidgets.QGraphicsView.AnchorUnderMouse)
self.setResizeAnchor(QtWidgets.QGraphicsView.AnchorUnderMouse)
self.drag = None
......@@ -47,16 +46,22 @@ class FilterView(QtWidgets.QGraphicsView):
self.measuringBoxes = []
def load_and_update_from_dataset(self, fname: str) -> None:
self.dataset = dataset.loadData(fname)
offset, diameter, widthHeight = helpers.get_filterDimensions_from_dataset(self.dataset)
offsetx = helpers.convert_length_to_pixels(self.dataset, offset[0])
offsety = helpers.convert_length_to_pixels(self.dataset, offset[1])
diameter = helpers.convert_length_to_pixels(self.dataset, diameter)
width = helpers.convert_length_to_pixels(self.dataset, widthHeight[0])
height = helpers.convert_length_to_pixels(self.dataset, widthHeight[1])
self.filter.update_filterSize(width, height, diameter, (offsetx, offsety))
self._update_particle_contours()
self._fit_to_window()
try:
self.dataset = dataset.loadData(fname)
except IndexError:
self.dataset = None
QtWidgets.QMessageBox.critical(self, 'Index Error', 'Unable to load dataset..')
if self.dataset is not None:
offset, diameter, widthHeight = helpers.get_filterDimensions_from_dataset(self.dataset)
offsetx = helpers.convert_length_to_pixels(self.dataset, offset[0])
offsety = helpers.convert_length_to_pixels(self.dataset, offset[1])
diameter = helpers.convert_length_to_pixels(self.dataset, diameter)
width = helpers.convert_length_to_pixels(self.dataset, widthHeight[0])
height = helpers.convert_length_to_pixels(self.dataset, widthHeight[1])
self.filter.update_filterSize(width, height, diameter, (offsetx, offsety))
self._update_particle_contours()
self._fit_to_window()
def _update_particle_contours(self) -> None:
self._remove_particle_contours()
......@@ -72,17 +77,18 @@ class FilterView(QtWidgets.QGraphicsView):
self.contourItems = []
def _update_measured_contours(self) -> None:
# offset = self.filter.circleOffset
# offset = (-offset[0], -offset[1])
offset = (0, 0)
def distanceToCnt(box: MeasureBoxGraphItem):
return abs(box.posX - cntStart[0]) + abs(box.posY - cntStart[1])
for contourItem in self.contourItems:
contourItem.isMeasured = False
for measBox in self.measuringBoxes:
cntStart: tuple = (contourItem.contourData[0, 0, 0], contourItem.contourData[0, 0, 1])
sortedmeasBoxes = sorted(self.measuringBoxes, key=distanceToCnt)
for measBox in sortedmeasBoxes:
topLeftXY = (measBox.posX, measBox.posY)
boxWidthHeight = (measBox.width, measBox.height)
if helpers.box_overlaps_contour(topLeftXY, boxWidthHeight, contourItem.polygon, offset=offset):
if helpers.box_overlaps_contour(topLeftXY, boxWidthHeight, contourItem.contourData):
contourItem.isMeasured = True
contourItem.update()
break
......
......@@ -32,39 +32,29 @@ class ParticleBinSorter(object):
return binIndex
def box_overlaps_contour(boxTopLeftXY: tuple, boxWidthHeight: tuple, contour, offset: tuple = (0, 0)) -> bool:
def box_overlaps_contour(boxTopLeftXY: tuple, boxWidthHeight: tuple, contourData: np.ndarray) -> bool:
"""
Calculates, if a contour is overlapping a box.
:param boxTopLeftXY: topLeft of Box
:param boxWidthHeight: Width and height of box
:param contour: np.ndarrayof contour data
:param offset: optional offset (x, y) of the box (i.e., the (0, 0) of the contours coord system does not match
the (0, 0) of the box coord system.
:param contourData: np.ndarrayof contour data
:return:
"""
contourPolygon = QtGui.QPolygonF()
if type(contour) == np.ndarray:
for point in contour:
contourPolygon.append(QtCore.QPointF(point[0, 0], point[0, 1]))
elif type(contour) == QtGui.QPolygonF:
contourPolygon = contour
else:
raise TypeError
boxPolygon = QtGui.QPolygonF()
boxPolygon.append(QtCore.QPointF(boxTopLeftXY[0]+offset[0], boxTopLeftXY[1]+offset[1]))
boxPolygon.append(QtCore.QPointF(boxTopLeftXY[0]+offset[0], boxTopLeftXY[1] + boxWidthHeight[1]+offset[1]))
boxPolygon.append(QtCore.QPointF(boxTopLeftXY[0]+offset[0] + boxWidthHeight[0], boxTopLeftXY[1]+offset[1]))
boxPolygon.append(QtCore.QPointF(boxTopLeftXY[0]+offset[0] + boxWidthHeight[0],
boxTopLeftXY[1] + boxWidthHeight[1]+offset[1]))
isOverlapping: bool = boxPolygon.intersects(contourPolygon)
if not isOverlapping:
# sometimes, the polygon.intersects method does not capture everything... We test the brects therefore..
polygonBrect: QtCore.QRectF = contourPolygon.boundingRect()
boxBrect: QtCore.QRectF = boxPolygon.boundingRect()
if boxBrect.contains(polygonBrect) or boxBrect.intersects(polygonBrect):
isOverlapping = True
isOverlapping: bool = False
xmin, xmax = np.min(contourData[:, 0, 0]), np.max(contourData[:, 0, 0])
width: float = xmax - xmin
boxXmin, boxXmax = boxTopLeftXY[0], boxTopLeftXY[0] + boxWidthHeight[0]
if xmin > (boxXmin-width/2):
if xmax < (boxXmax+width/2):
ymin, ymax = np.min(contourData[:, 0, 1]), np.max(contourData[:, 0, 1])
height = ymax - ymin
boxYmin, boxYmax = boxTopLeftXY[1], boxTopLeftXY[1] + boxWidthHeight[1]
if ymin > (boxYmin-height/2):
if ymax < (boxYmax+width/2):
isOverlapping = True
return isOverlapping
......
......@@ -78,15 +78,14 @@ class TestOther(unittest.TestCase):
contourPoints = np.array([[[1, 1]], [[5, 5]], [[3, 3]]]) # fully enclosed
self.assertTrue(helpers.box_overlaps_contour(boxXY, boxWidthHeight, contourPoints))
contourPoints = np.array([[[-5, -5]], [[0, 5]], [[-5, -10]]]) # only one point touches border
contourPoints = np.array([[[-5, -5]], [[-1, 5]], [[-5, -10]]]) # outside the box
self.assertFalse(helpers.box_overlaps_contour(boxXY, boxWidthHeight, contourPoints))
contourPoints = np.array([[[-2.5, 0]], [[5, 0]], [[5, 5]], [[-2.5, 5]]]) # inside more than 50 %
self.assertTrue(helpers.box_overlaps_contour(boxXY, boxWidthHeight, contourPoints))
offset: tuple = (1, 0) # now it does not touch it anymore
self.assertFalse(helpers.box_overlaps_contour(boxXY, boxWidthHeight, contourPoints, offset))
contourPoints = np.array([[[-5, -5]], [[-1, 5]], [[-5, -10]]]) # outside the box
contourPoints = np.array([[[-2.5, 0]], [[2, 0]], [[2, 2]], [[-2.5, 2]]]) # inside less than 50 %
self.assertFalse(helpers.box_overlaps_contour(boxXY, boxWidthHeight, contourPoints))
offset = (-5, -5) # now it overlaps
self.assertTrue(helpers.box_overlaps_contour(boxXY, boxWidthHeight, contourPoints, offset))
def test_get_overlapping_fraction(self):
polygon1: QtGui.QPolygonF = QtGui.QPolygonF()
......
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