Java tutorial
/*********************************************************************** Legacy Film to DVD Project Copyright (C) 2005 James F. Carroll This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ****************************************************************************/ package com.jiminger.image.houghspace.internal; import org.opencv.core.CvType; import org.opencv.core.Mat; import com.jiminger.image.houghspace.Model; /** * <p>A mask underpinned by an array of bytes, each containing an indication as to whether or not * that position is the center of the model, if the center of the mask is on an EDGE in the * original image.</p> * * <p>What does that mean? If you take this mask and place it centered at an edge in the original * image, then everywhere that this mask reads NON-zero is potentially a "center" of the model * in the original image.</p> */ public class Mask { public static byte EDGE = (byte) -1; public static byte NOEDGE = (byte) 0; public final int mwidth; public final int mheight; /** * Mask center, row */ public final int maskcr; /** * Mask center, column */ public final int maskcc; /** * monochrome image of the mask */ public final byte[] mask; /** * Instantiate a mask of the given dimensions assuming * that the reference point is the center of the mask. */ private Mask(int mwidth, int mheight) { // mwidth and mheight need to be odd // so that the center falls exactly // on a pixel. mwidth += (((mwidth & 0x01) == 0) ? 1 : 0); mheight += (((mheight & 0x01) == 0) ? 1 : 0); this.mwidth = mwidth; this.mheight = mheight; this.mask = new byte[mwidth * mheight]; this.maskcr = (this.mheight + 1) / 2 - 1; this.maskcc = (this.mwidth + 1) / 2 - 1; } /** * Generate an OpenCV Mat image that contains a view of the mask. */ public Mat getMaskImage() { final Mat m = new Mat(mheight, mwidth, CvType.CV_8UC1); m.put(0, 0, mask); return m; } /** * Set the value of the mask at a location to * the given value. The value should be either * EDGE or NOEDGE. Entries in the mask are * accessed by row and column (not x,y). */ private void set(final int r, final int c, final byte v) { mask[(r * mwidth) + c] = v; } public static Mask generateMask(final Model m, final double quantFactor, final double scaleModel) { final double w = m.featureWidth() * scaleModel; final double h = m.featureHeight() * scaleModel; // mask is 1 pixel wider than w and higher than h // round(w/quant + 1) = (int)((w/quant) + 1.5) final Mask mask = new Mask((int) ((w / quantFactor) + 1.5), (int) ((h / quantFactor) + 1.5)); // now set the mask by sweeping the center final double x0 = mask.maskcc; // x0,y0 is the final double y0 = mask.maskcr; // origin of // the mask for (int r = 0; r < mask.mheight; r++) { for (int c = 0; c < mask.mwidth; c++) { // is the point r,c a possible model // center if an edge appears at the // center of the mask? // to figure this out, translate // r,c to the center. // but first, find out what r,c is // in the coordinate system of the // mask with the origin centered. final double y1 = mask.mheight - r - 1 - y0; final double x1 = (c) - x0; // now, if x1,y1 is the center // of the sprocket hole, will // the origin be on the sprocket? // That means we need to check // -x1,-y1 since that is where // the origin will be pushed to // upon translating x1,y1 to the // origin. final double dist = m.distance(-(x1 * quantFactor), -(y1 * quantFactor), 0.0, 1.0); // if we are within a 1/2 pixel of the // theoretical sprocket then we're on it. if (dist <= quantFactor / 2.0) mask.set(r, c, EDGE); else mask.set(r, c, NOEDGE); } } return mask; } public static void setEdgePixVals(final byte edgePixVal, final byte noedgePixVal) { EDGE = edgePixVal; NOEDGE = noedgePixVal; } }