In a binary image the contour on the right and bottom is off by one pixel. This is because the block region
extends the entire pixel not just the lower extent which is where it is indexed from.
765665
protected void adjustElipseForBinaryBias( EllipseRotated_F64 ellipse ) {
		ellipse.center.x += 0.5;
		ellipse.center.y += 0.5;

		ellipse.a += 0.5;
		ellipse.b += 0.5;
	}
410122
function getGrabberOffsetPixelFromPercent(percentOffset) {
			var sbLenght = getHeightArea(); // Longueur de la scrollbar
			var grabberOffsetPixel = sbLenght * percentOffset / 100;
			return Math.max(grabberOffsetPixel, 0);
		}
220501
def bitdepthof(pixel):
    """"""

    maxd = 0
    for c in re.findall(r'[a-z]\d*', pixel):
        if c[0] != 'x':
            maxd = max(maxd, int(c[1:]))
    return maxd
1326721
private void boundaryAreaExteriorLine_(int half_edge, int id_a, int id_b) {
		if (m_matrix[MatrixPredicate.BoundaryExterior] == 1)
			return;

		int parentage = m_topo_graph.getHalfEdgeParentage(half_edge);

		if ((parentage & id_a) != 0 && (parentage & id_b) == 0)
			m_matrix[MatrixPredicate.BoundaryExterior] = 1;

	}
554917
def outline(self, inner, outer):
        
        return self.dilate(outer).exclude(self.dilate(inner))
1341592
private void findCandidateShapes() {

		// find blobs where all 4 edges are lines
		List<ContourPacked> blobs = contourFinder.getContours();
		for (int i = 0; i < blobs.size(); i++) {
			ContourPacked c = blobs.get(i);

			contourTmp.reset();
			contourFinder.loadContour(c.externalIndex,contourTmp);
			if( contourTmp.size() >= minimumContour) {
				float edgeInside=-1,edgeOutside=-1;

//				System.out.println("----- candidate "+contourTmp.size()+"  "+contourTmp.get(0));

				// ignore shapes which touch the image border
				boolean touchesBorder = touchesBorder(contourTmp.toList());
				if( !canTouchBorder && touchesBorder ) {
					if( verbose ) System.out.println("rejected polygon, touched border");
					continue;
				}

				if( helper != null )
					if( !helper.filterContour(contourTmp.toList(),touchesBorder,true) )
						continue;

				// filter out contours which are noise
				if( contourEdgeIntensity != null ) {
					contourEdgeIntensity.process(contourTmp.toList(),true);
					edgeInside = contourEdgeIntensity.getInsideAverage();
					edgeOutside = contourEdgeIntensity.getOutsideAverage();

					// take the ABS because CCW/CW isn't known yet
					if( Math.abs(edgeOutside-edgeInside) < contourEdgeThreshold ) {
						if( verbose ) System.out.println("rejected polygon. contour edge intensity");
						continue;
					}
				}

				// remove lens distortion
				List<Point2D_I32> undistorted;
				if( distToUndist != null ) {
					undistorted = this.undistorted.toList();
					removeDistortionFromContour(contourTmp.toList(),this.undistorted);
					if( helper != null )
						if( !helper.filterContour(this.undistorted.toList(),touchesBorder,false) )
							continue;
				} else {
					undistorted = contourTmp.toList();
				}

				if( helper != null ) {
					helper.configureBeforePolyline(contourToPolyline,touchesBorder);
				}

				// Find the initial approximate fit of a polygon to the contour
				if( !contourToPolyline.process(undistorted,splits) ) {
					if( verbose ) System.out.println("rejected polygon initial fit failed. contour size = "+contourTmp.size());
					continue;
				}

				// determine the polygon's orientation
				polygonPixel.clear();
				for (int j = 0; j < splits.size; j++) {
					polygonPixel.add(undistorted.get(splits.get(j)));
				}

				boolean isCCW = UtilPolygons2D_I32.isCCW(polygonPixel);

				// Now that the orientation is known it can check to see if it's actually trying to fit to a
				// white blob instead of a black blob
				if( contourEdgeIntensity != null ) {
					// before it assumed it was CCW
					if( !isCCW ) {
						float tmp = edgeInside;
						edgeInside = edgeOutside;
						edgeOutside = tmp;
					}

					if( edgeInside > edgeOutside ) {
						if( verbose ) System.out.println("White blob. Rejected");
						continue;
					}
				}

				// see if it should be flipped so that the polygon has the correct orientation
				if( outputClockwise == isCCW ) {
					flip(splits.data,splits.size);
				}

				// convert the format of the initial crude polygon
				polygonWork.vertexes.resize(splits.size());
				polygonDistorted.vertexes.resize(splits.size());
				for (int j = 0; j < splits.size(); j++) {
					Point2D_I32 p = undistorted.get( splits.get(j) );
					Point2D_I32 q = contourTmp.get( splits.get(j));
					polygonWork.get(j).set(p.x,p.y);
					polygonDistorted.get(j).set(q.x,q.y);
				}

				if( touchesBorder ) {
					determineCornersOnBorder(polygonDistorted, borderCorners);
				} else {
					borderCorners.resize(0);
				}

				if( helper != null ) {
					if( !helper.filterPixelPolygon(polygonWork,polygonDistorted,borderCorners,touchesBorder) ) {
						if( verbose ) System.out.println("rejected by helper.filterPixelPolygon()");
						continue;
					}
				}

				// make sure it's big enough
				double area = Area2D_F64.polygonSimple(polygonWork);

				if( area < minimumArea ) {
					if( verbose ) System.out.println("Rejected area");
					continue;
				}

				// Get the storage for a new polygon. This is recycled and has already been cleaned up
				Info info = foundInfo.grow();

				if( distToUndist != null ) {
					// changed the save points in the packed contour list with undistorted coordinates
					contourFinder.writeContour(c.externalIndex,undistorted);
				}

				// save results
				info.splits.setTo(splits);
				info.contourTouchesBorder = touchesBorder;
				info.external = true;
				info.edgeInside = edgeInside;
				info.edgeOutside = edgeOutside;
				info.contour = c;
				info.polygon.set(polygonWork);
				info.polygonDistorted.set(polygonDistorted);
				info.borderCorners.setTo(borderCorners);
			}
		}
	}
336640
def bg_compensate(img, sigma, splinepoints, scale):
    ''''''
    
    from PIL import Image
    import pylab
    from matplotlib.image import pil_to_array
    from centrosome.filter import canny
    import matplotlib

    img = Image.open(img)
    if img.mode=='I;16':
        # 16-bit image
        # deal with the endianness explicitly... I'm not sure
        # why PIL doesn't get this right.
        imgdata = np.fromstring(img.tostring(),np.uint8)
        imgdata.shape=(int(imgdata.shape[0]/2),2)
        imgdata = imgdata.astype(np.uint16)
        hi,lo = (0,1) if img.tag.prefix == 'MM' else (1,0)
        imgdata = imgdata[:,hi]*256 + imgdata[:,lo]
        img_size = list(img.size)
        img_size.reverse()
        new_img = imgdata.reshape(img_size)
        # The magic # for maximum sample value is 281
        if 281 in img.tag:
            img = new_img.astype(np.float32) / img.tag[281][0]
        elif np.max(new_img) < 4096:
            img = new_img.astype(np.float32) / 4095.
        else:
            img = new_img.astype(np.float32) / 65535.
    else:
        img = pil_to_array(img)
    
    pylab.subplot(1,3,1).imshow(img, cmap=matplotlib.cm.Greys_r)
    pylab.show()
    
    if len(img.shape)>2:
        raise ValueError('Image must be grayscale')

## Create mask that will fix problem when image has black areas outside of well
    edges = canny(img, np.ones(img.shape, bool), 2, .1, .3)
    ci = np.cumsum(edges, 0)
    cj = np.cumsum(edges, 1)
    i,j = np.mgrid[0:img.shape[0], 0:img.shape[1]]
    mask = ci > 0
    mask = mask & (cj > 0)
    mask[1:,:] &= (ci[0:-1,:] < ci[-1,j[0:-1,:]])
    mask[:,1:] &= (cj[:,0:-1] < cj[i[:,0:-1],-1])
    
    import time
    t0 = time.clock()
    bg = backgr(img, mask, MODE_AUTO, sigma, splinepoints=splinepoints, scale=scale)
    print("Executed in %f sec" % (time.clock() - t0))
    bg[~mask] = img[~mask]

    pylab.subplot(1,3,2).imshow(img - bg, cmap=matplotlib.cm.Greys_r)
    pylab.subplot(1,3,3).imshow(bg, cmap=matplotlib.cm.Greys_r)
    pylab.show()
533539
public void process(T gray , GrayU8 binary ) {
		detector.process(gray,binary);
		if( refineGray != null )
			refineGray.setImage(gray);
		edgeIntensity.setImage(gray);

		long time0 = System.nanoTime();
		FastQueue<DetectPolygonFromContour.Info> detections = detector.getFound();

		if( adjustForBias != null ) {
			int minSides = getMinimumSides();
			for (int i = detections.size()-1; i >= 0; i-- ) {
				Polygon2D_F64 p = detections.get(i).polygon;
				adjustForBias.process(p, detector.isOutputClockwise());

				// When the polygon is adjusted for bias a point might need to be removed because it's
				// almost parallel. This could cause the shape to have too few corners and needs to be removed.
				if( p.size() < minSides)
					detections.remove(i);
			}
		}
		long time1 = System.nanoTime();

		double milli = (time1-time0)*1e-6;

		milliAdjustBias.update(milli);
//		System.out.printf(" contour %7.2f shapes %7.2f adjust_bias %7.2f\n",
//				detector.getMilliShapes(),detector.getMilliShapes(),milliAdjustBias);
	}
1113271
function matchSegment(ax, ay, bx, by, cx, cy, dx, dy, r, result) {
    var len = result.length;

    var ap = closePoint(ax, ay, cx, cy, dx, dy, r);
    var bp = closePoint(bx, by, cx, cy, dx, dy, r);

    //     a----b
    // c---ap---bp---d
    if (ap !== null && bp !== null) return true; // fully covered

    var cp = closePoint(cx, cy, ax, ay, bx, by, r);
    var dp = closePoint(dx, dy, ax, ay, bx, by, r);

    if (cp !== null && cp === dp) return false; // degenerate case, no overlap

    var cpx, cpy, dpx, dpy;
    if (cp !== null) {
        cpx = interp(ax, bx, cp);
        cpy = interp(ay, by, cp);
    }
    if (dp !== null) {
        dpx = interp(ax, bx, dp);
        dpy = interp(ay, by, dp);
    }

    if (cp !== null && dp !== null) {

        if (cpx === dpx && cpy === dpy) return false; // degenerate case

        // a---cp---dp---b
        //     c----d
        if (cp < dp) {
            if (!equals(ax, ay, cpx, cpy)) addSegment(result, ax, ay, cpx, cpy);
            if (!equals(dpx, dpy, bx, by)) addSegment(result, dpx, dpy, bx, by);

        // a---dp---cp---b
        //     d----c
        } else {
            if (!equals(ax, ay, dpx, dpy)) addSegment(result, ax, ay, dpx, dpy);
            if (!equals(cpx, cpy, bx, by)) addSegment(result, cpx, cpy, bx, by);
        }

    } else if (cp !== null) {
        //     a----cp---b
        // d---ap---c
        if (ap !== null && !equals(ax, ay, cpx, cpy)) addSegment(result, cpx, cpy, bx, by);

        // a---cp---b
        //     c----bp---d
        else if (bp !== null && !equals(cpx, cpy, bx, by)) addSegment(result, ax, ay, cpx, cpy);

    } else if (dp !== null) {
        // a---dp---b
        //     d----bp---c
        if (bp !== null && !equals(dpx, dpy, bx, by)) addSegment(result, ax, ay, dpx, dpy);

        //     a----dp---b
        // c---ap---d
        else if (ap !== null && !equals(ax, ay, dpx, dpy)) addSegment(result, dpx, dpy, bx, by);
    }

    return result.length !== len; // segment processed
}
15609
public static void horizontalInverse(BorderIndex1D border , WlBorderCoef<WlCoef_I32> inverseCoef , GrayI input , GrayI output ) {

		UtilWavelet.checkShape(output,input);

		int []trends = new int[ output.width ];
		int []details = new int[ output.width ];

		boolean isLarger = input.width >= output.width;
		int paddedWidth = output.width + output.width%2;

		final int lowerBorder = inverseCoef.getLowerLength()*2;
		final int upperBorder = output.width - inverseCoef.getUpperLength()*2;

		border.setLength(output.width+output.width%2);

		WlCoef_I32 coefficients = inverseCoef.getInnerCoefficients();
		final int e = coefficients.denominatorScaling*2;
		final int f = coefficients.denominatorWavelet*2;
		final int ef = e*f;
		final int ef2 = ef/2;

		for( int y = 0; y < output.height; y++ ) {

			for( int i = 0; i < details.length; i++ ) {
				details[i] = 0;
				trends[i] = 0;
			}

			for( int x = 0; x < output.width; x += 2 ) {
				int a = input.get(x/2,y);
				int d = input.get(input.width/2+x/2,y);

				if( x < lowerBorder ) {
					coefficients = inverseCoef.getBorderCoefficients(x);
				} else if( x >= upperBorder ) {
					coefficients = inverseCoef.getBorderCoefficients(x-paddedWidth);
				} else {
					coefficients = inverseCoef.getInnerCoefficients();
				}

				final int offsetA = coefficients.offsetScaling;
				final int offsetB = coefficients.offsetWavelet;
				final int[] alpha = coefficients.scaling;
				final int[] beta = coefficients.wavelet;

				// add the trend
				for( int i = 0; i < alpha.length; i++ ) {
					// if an odd image don't update the outer edge
					int xx = border.getIndex(x+offsetA+i);
					if( isLarger && xx >= output.width )
						continue;
					trends[xx] += a*alpha[i];
				}

				// add the detail signal
				for( int i = 0; i < beta.length; i++ ) {
					int xx = border.getIndex(x+offsetB+i);
					if( isLarger && xx >= output.width )
						continue;
					details[xx] += d*beta[i];
				}
			}

			for( int x = 0; x < output.width; x++ ) {
				output.set(x,y, UtilWavelet.round(trends[x]*f + details[x]*e ,ef2,ef));
			}
		}
	}
1010278
public void transform( GrayU8 binary )
	{
		ImageMiscOps.fill(transform, 0);

		originX = binary.width/2;
		originY = binary.height/2;
		r_max = Math.sqrt(originX*originX+originY*originY);

		for( int y = 0; y < binary.height; y++ ) {
			int start = binary.startIndex + y*binary.stride;
			int stop = start + binary.width;

			for( int index = start; index < stop; index++ ) {
				if( binary.data[index] != 0 ) {
					parameterize(index-start,y);
				}
			}
		}
	}
726682
private void boundaryAreaExteriorArea_(int half_edge, int id_a, int id_b,
			int predicate) {
		if (m_matrix[predicate] == 1)
			return;

		int faceParentage = m_topo_graph.getHalfEdgeFaceParentage(half_edge);
		int twinFaceParentage = m_topo_graph
				.getHalfEdgeFaceParentage(m_topo_graph
						.getHalfEdgeTwin(half_edge));

		if ((faceParentage & id_b) == 0 && (twinFaceParentage & id_b) == 0)
			m_matrix[predicate] = 1;
	}
705357
public static void horizontal(Kernel1D_F64 kernel, GrayF64 src, GrayF64 dst ) {
		InputSanityCheck.checkSameShape(src, dst);

		boolean processed = BOverrideConvolveImageNormalized.invokeNativeHorizontal(kernel,src,dst);
		
		if( !processed ) {
			if( kernel.width >= src.width ) {
				ConvolveNormalizedNaive_SB.horizontal(kernel,src,dst);
			} else {
				if( Math.abs(kernel.computeSum() - 1.0f) > 1e-4f ) {
					Kernel1D_F64 k = kernel.copy();
					KernelMath.normalizeSumToOne(k);
					kernel = k;
				}
				ConvolveImageNoBorder.horizontal(kernel,src,dst);
				ConvolveNormalized_JustBorder_SB.horizontal(kernel,src,dst);
			}
		}
	}
1150741
private static int[] findLeftMostVertex(Contour contour) {
        int minx = contour.verts[0];
        int minz = contour.verts[2];
        int leftmost = 0;
        for (int i = 1; i < contour.nverts; i++) {
            int x = contour.verts[i * 4 + 0];
            int z = contour.verts[i * 4 + 2];
            if (x < minx || (x == minx && z < minz)) {
                minx = x;
                minz = z;
                leftmost = i;
            }
        }
        return new int[] { minx, minz, leftmost };
    }
843917
public void process( GrayU8 binary ) {
		found.reset();
		labeled.reshape(binary.width, binary.height);

		contourFinder.process(binary, labeled);

		List<ContourPacked> blobs = contourFinder.getContours();
		for (int i = 0; i < blobs.size(); i++) {
			ContourPacked c = blobs.get(i);

			contourFinder.loadContour(c.externalIndex,contourTmp);
			proccessContour(contourTmp.toList());

			if(internalContour) {
				for( int j = 0; j < c.internalIndexes.size(); j++ ) {
					contourFinder.loadContour(c.internalIndexes.get(j),contourTmp);
					proccessContour(contourTmp.toList());
				}
			}
		}
	}
1197363
private Shape decodeMarkBorder(int width, int height) {
        int left = (width - 3) / 2 - 5;
        int top  = (height - 2) / 2 - 5;

        path.reset();
        path.moveTo(left + 1, top + 0);
        path.lineTo(left + 3, top + 0);
        path.pointAt(left + 4, top + 1);
        path.pointAt(left + 5, top + 2);
        path.pointAt(left + 6, top + 1);
        path.moveTo(left + 7, top + 0);
        path.lineTo(left + 9, top + 0);
        path.pointAt(left + 10, top + 1);
        path.pointAt(left + 9, top + 2);
        path.pointAt(left + 8, top + 3);
        path.moveTo(left + 7, top + 4);
        path.lineTo(left + 7, top + 5);
        path.pointAt(left + 8, top + 6);
        path.pointAt(left + 9, top + 7);
        path.pointAt(left + 10, top + 8);
        path.moveTo(left + 9, top + 9);
        path.lineTo(left + 7, top + 9);
        path.pointAt(left + 6, top + 8);
        path.pointAt(left + 5, top + 7);
        path.pointAt(left + 4, top + 8);
        path.moveTo(left + 3, top + 9);
        path.lineTo(left + 1, top + 9);
        path.pointAt(left + 0, top + 8);
        path.pointAt(left + 1, top + 7);
        path.pointAt(left + 2, top + 6);
        path.moveTo(left + 3, top + 5);
        path.lineTo(left + 3, top + 4);
        path.pointAt(left + 2, top + 3);
        path.pointAt(left + 1, top + 2);
        path.pointAt(left + 0, top + 1);

        return path;
    }
1083243
def inverse(self):
        
        data = np.zeros(self.shape).astype(np.uint8)
        ind = np.where(self.data == 0)
        data[ind[0], ind[1], ...] = BINARY_IM_MAX_VAL
        return BinaryImage(data, self._frame)