def test_polyintersect(self): x1 = np.array([(0, 0), (1, 1), (1, 0)]) x2 = np.array([(1, 0), (1.5, 1.5), (.5, 0.5)]) intersection_polygon = pgeometry.polyintersect(x1, x2) self.assertEqual(4, len(intersection_polygon)) self.assertEqual(0.25, np.abs(pgeometry.polyarea(intersection_polygon)))
def test_non_convex_intersection(self): delta = .5 x1 = np.array([(-1, -1), (1, -1), (1, 1), (-1, 1)]) x2 = np.array([(delta, 0), (5, 5), (-5, 5), (-delta, 0), (-5, -5), (5, -5), (delta, 0)]) intersection_polygon = pgeometry.polyintersect(x1, x2) self.assertEqual(intersection_polygon.shape, (11, 2)) self.assertEqual(np.abs(pgeometry.polyarea(intersection_polygon)), 31 / 9)
def costscoreOD(a, b, pt, ww, verbose=0, output=False): """ Cost function for simple fit of one-dot open area Args: a,b (float): position along axis (a is the x-axis) pt (numpy array): point in image ww (array) verbose (int) output (bool) Returns: cost (float) """ pts = np.array([[a, 0], pt, [ww.shape[1] - 1, b], [ww.shape[1] - 1, 0], [a, 0]]) pts = pts.reshape((5, 1, 2)).astype(int) imx = 0 * ww.copy().astype(np.uint8) cv2.fillConvexPoly(imx, pts, color=[1]) area = np.abs(pgeometry.polyarea(pts.reshape((-1, 2)))) cost = -(imx == ww).sum() # add penalty for moving out of range cost += (.025 * ww.size) * np.maximum(b - ww.shape[0] - 1, 0) / ww.shape[0] cost += (.025 * ww.size) * np.maximum(-a, 0) / ww.shape[1] cost += (.025 * ww.size) * 2 * (pts[2, 0, 1] < 0) cost += (.025 * ww.size) * 2 * (pt[0] < 0) # x too far left cost += (.025 * ww.size) * 2 * (pt[1] > ww.shape[0]) # y too far down cost += 1e-3 * area if verbose: print('costscore %.2f' % cost) if output: return cost, pts, imx else: return cost
def evaluateCross(param, im, verbose=0, fig=None, istep=1, istepmodel=1, linewidth=2, usemask=False, use_abs=False, w=2.5): """ Calculate cross matching score Args: param (array or list): used by createCross to create image template im (numpy array): Returns: cost, patch, cdata, tuple See also: createCross """ samplesize = [int(im.shape[1] * istep / istepmodel), int(im.shape[0] * istep / istepmodel)] param = np.array(param) aa = param[3:] H = evaluateCross.scaling0.copy() H[0, 0] = istep / istepmodel H[1, 1] = istep / istepmodel dsize = (samplesize[0], samplesize[1]) patch = cv2.warpPerspective(im.astype(np.float32), H, dsize, None, (cv2.INTER_LINEAR), cv2.BORDER_CONSTANT, -1) if verbose: print('evaluateCross: patch shape %s' % (patch.shape,)) modelpatch, cdata = createCross(param, samplesize, centermodel=False, istep=istepmodel, verbose=verbose >= 2, w=w) (cc, lp, hp, ip, op, _, _, _) = cdata if use_abs: dd = np.abs(patch) - modelpatch else: dd = patch - modelpatch if usemask: # near model mask #mask = (modelpatch>1).astype(int) # distance centre mask imtmp = 10 + 0 * modelpatch.copy() imtmp[int(imtmp.shape[1] / 2), int(imtmp.shape[0] / 2)] = 0 mask = scipy.ndimage.distance_transform_edt(imtmp) mask = 1 - .75 * mask / mask.max() dd = dd * mask cost = np.linalg.norm(dd) # area of intersection rr = np.array([[0., im.shape[1]], [0, im.shape[0]]]) ppx = pgeometry.region2poly(np.array([[0, samplesize[0]], [0., samplesize[1]]])) ppimage = pgeometry.region2poly(rr) pppatch = pgeometry.projectiveTransformation(H, ppimage) ppi = pgeometry.polyintersect(ppx.T, pppatch.T).T A = pgeometry.polyarea(ppi.T) A0 = pgeometry.polyarea(ppx.T) # special rules if np.abs(A / A0) < .85: if verbose: print(' add cost for A/A0: A %f A0 %f' % (A, A0)) cost += 4000 if aa[0] < 0 or aa[0] > np.pi / 2 - np.deg2rad(5): cost += 10000 if aa[1] < np.pi or aa[1] > 3 * np.pi / 2: if verbose: print(' add cost for alpha') cost += 10000 if aa[2] < np.pi or aa[2] > 3 * np.pi / 2: if verbose: print(' add cost for alpha') cost += 10000 if aa[3] < 0 or aa[3] > np.pi / 2: if verbose: print(' add cost for alpha') cost += 10000 if 1: ccim = (np.array(im.shape) / 2 + .5) * istep tmp = np.linalg.norm(ccim - param[0:2]) dcost = 2000 * pgeometry.logistic(tmp, np.mean(ccim), istep) if verbose: print(' add cost for image cc: %.1f' % dcost) cost += dcost if pgeometry.angleDiff(aa[0], aa[1]) < np.deg2rad(30): if verbose: print(' add cost for angle diff') cost += 1000 if pgeometry.angleDiff(aa[2], aa[3]) < np.deg2rad(30): if verbose: print(' add cost for angle diff') cost += 1000 if pgeometry.angleDiffOri(aa[0], aa[2]) > np.deg2rad(10): cost += 10000 if pgeometry.angleDiffOri(aa[1], aa[3]) > np.deg2rad(10): cost += 10000 if param[2] < 0: if verbose: print(' add cost for negative param') cost += 10000 if np.abs(param[2]) > 7.: if verbose: print(' add cost large param[2]') cost += 10000 if np.abs(param[2] - 10) > 8: cost += 10000 if len(param) > 7: if np.abs(pgeometry.angleDiff(param[7], np.pi / 4)) > np.deg2rad(30): cost += 10000 if not fig is None: _showIm(patch, fig=fig) plt.title('Image patch: cost %.1f: istep %.2f' % (cost, istepmodel)) pgeometry.addfigurecopy(fig=fig) plt.plot([float(lp[0]), float(hp[0])], [float(lp[1]), float(hp[1])], '.--m', linewidth=linewidth, markersize=10, label='transition line') plt.plot(cc[0], cc[1], '.m', markersize=12) for ii in range(4): if ii == 0: lbl = 'electron line' else: lbl = None plt.plot([op[ii, 0], ip[ii, 0]], [op[ii, 1], ip[ii, 1]], '.-', linewidth=linewidth, color=[0, .7, 0], label=lbl) pgeometry.plotLabels(np.array((op[ii, :] + ip[ii, :]) / 2).reshape((2, -1)), '%d' % ii) if verbose >= 1: _showIm(modelpatch, fig=fig + 1) plt.title('Model patch: cost %.1f' % cost) _showIm(np.abs(dd), fig=fig + 2) plt.title('diff patch: cost %.1f' % cost) plt.colorbar() plt.show() if verbose: print('evaluateCross: cost %.4f' % cost) #print('evaluateCross: param %s' % (str(param), )) return cost, patch, cdata, (H, ) pass