/*
* Copyright (c) 2011-2016, Peter Abeles. All Rights Reserved.
*
* This file is part of BoofCV (http://boofcv.org).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package boofcv.alg.fiducial.calib;
import boofcv.alg.misc.ImageMiscOps;
import boofcv.struct.image.GrayF32;
import georegression.struct.point.Point2D_F64;
import georegression.struct.shapes.Quadrilateral_F64;
import java.util.ArrayList;
import java.util.List;
/**
* Renders the fiducial for use in unit tests
*
* @author Peter Abeles
*/
public class RenderSquareBinaryGridFiducial {
public double border = 0.25;
public int binaryGrid = 3;
public int squareWidth = 40;
public List<Quadrilateral_F64> expectedCorners = new ArrayList<>();
public List<Point2D_F64> getOrderedExpectedPoints( int numRows, int numCols ) {
List<Point2D_F64> points = new ArrayList<>();
for (int row = 0; row < numRows; row++) {
for (int col = 0; col < numCols; col++) {
Quadrilateral_F64 q = expectedCorners.get(row*numCols+col);
points.add(q.a);
points.add(q.b);
}
for (int col = 0; col < numCols; col++) {
Quadrilateral_F64 q = expectedCorners.get(row*numCols+col);
points.add(q.d);
points.add(q.c);
}
}
return points;
}
public GrayF32 generate(int numRows, int numCols ) {
expectedCorners.clear();
int imageWidth = (numCols*2+2)*squareWidth;
int imageHeight = (numRows*2+2)*squareWidth;
GrayF32 image = new GrayF32(imageWidth,imageHeight);
ImageMiscOps.fill(image, 255);
int number = 0;
for (int i = 0; i < numRows; i++) {
int y0 = i*squareWidth*2 + squareWidth;
for (int j = 0; j < numCols; j++) {
int x0 = j*squareWidth*2 + squareWidth;
generateSquare(x0,y0,squareWidth,number++,image);
}
}
return image;
}
private void generateSquare( int x0 , int y0 , int width , int value , GrayF32 image ) {
ImageMiscOps.fillRectangle(image,0,x0,y0,width,width);
int innerWidth = (int)(width*(1.0-border*2)+0.5);
int x1 = x0+(width-innerWidth)/2;
int y1 = y0+(width-innerWidth)/2;
expectedCorners.add(new Quadrilateral_F64(x0,y0, x0+width,y0, x0+width,y0+width, x0,y0+width));
int bit = 0;
for( int row = 0; row < binaryGrid; row++ ) {
int pixelY0 = y1 + innerWidth-(row+1)*innerWidth/binaryGrid;
int pixelY1 = y1 + innerWidth-(row)*innerWidth/binaryGrid;
for (int col = 0; col < binaryGrid; col++) {
int pixelX0 = x1 + col*innerWidth/binaryGrid;
int pixelX1 = x1 + (col+1)*innerWidth/binaryGrid;
boolean white;
if( row ==0 && col == 0)
white = false;
else if ( row ==0 && col == binaryGrid-1)
white = true;
else if ( row ==binaryGrid-1 && col == binaryGrid-1)
white = true;
else if ( row ==binaryGrid-1 && col == 0)
white = true;
else {
white = ((value >> bit) & 0x01) == 0;
bit++;
}
if( white ) {
ImageMiscOps.fillRectangle(image,255, pixelX0,pixelY0, pixelX1-pixelX0,pixelY1-pixelY0);
}
}
}
}
}