/*
* 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.segmentation.fh04.impl;
import boofcv.misc.AutoTypeImage;
import boofcv.misc.CodeGeneratorBase;
import boofcv.struct.ConnectRule;
import java.io.FileNotFoundException;
/**
* @author Peter Abeles
*/
public class GenerateFhEdgeWeights_PL extends CodeGeneratorBase {
@Override
public void generate() throws FileNotFoundException {
create(AutoTypeImage.F32,ConnectRule.EIGHT);
create(AutoTypeImage.U8,ConnectRule.EIGHT);
create(AutoTypeImage.F32,ConnectRule.FOUR);
create(AutoTypeImage.U8,ConnectRule.FOUR);
}
protected void create( AutoTypeImage imageType , ConnectRule rule) throws FileNotFoundException {
String name = "FhEdgeWeights"+rule.getShortName()+"_PL"+imageType.getAbbreviatedType();
setOutputFile(name);
printPreamble(imageType,rule);
printConstructor(imageType);
printProcess(imageType,rule);
printCheckAround(imageType,rule);
printCheck(imageType);
printType(imageType);
out.print("}\n");
}
private void printPreamble( AutoTypeImage imageType , ConnectRule rule ) {
String imageName = imageType.getSingleBandName();
String ruleName = rule.getShortName();
out.print("import boofcv.struct.image."+imageName+";\n" +
"import boofcv.struct.image.ImageType;\n" +
"import boofcv.alg.segmentation.fh04.FhEdgeWeights;\n" +
"import boofcv.struct.image.Planar;\n" +
"import org.ddogleg.struct.FastQueue;\n" +
"\n" +
"import static boofcv.alg.segmentation.fh04.SegmentFelzenszwalbHuttenlocher04.Edge;\n" +
"\n" +
"/**\n" +
" * <p>Computes edge weight as the F-norm different in pixel value for {@link Planar} images.\n" +
" * A "+ruleName+"-connect neighborhood is considered.</p>\n" +
" *\n" +
" * <p>\n" +
" * WARNING: Do not modify. Automatically generated by {@link "+getClass().getSimpleName()+"}.\n" +
" * </p>\n" +
" *\n" +
" * @author Peter Abeles\n" +
" */\n" +
"public class "+className+" implements FhEdgeWeights<Planar<"+imageName+">> {\n\n");
}
private void printConstructor( AutoTypeImage imageType ) {
String sumType = imageType.getSumType();
out.print("\t"+sumType+" pixelColor[];\n" +
"\tint numBands;\n" +
"\n" +
"\tpublic "+className+"(int numBands) {\n" +
"\t\tthis.numBands = numBands;\n" +
"\t\tpixelColor = new "+sumType+"[numBands];\n" +
"\t}\n\n");
}
private void printProcess( AutoTypeImage imageType , ConnectRule rule ) {
String imageName = imageType.getSingleBandName();
String sumType = imageType.getSumType();
String bitwise = imageType.getBitWise();
int startX = rule == ConnectRule.FOUR ? 0 : 1;
String weightString = rule == ConnectRule.EIGHT ? ",weight3=0,weight4=0" : "";
out.print("\t@Override\n" +
"\tpublic void process(Planar<"+imageName+"> input,\n" +
"\t\t\t\t\t\tFastQueue<Edge> edges) {\n" +
"\n" +
"\t\tedges.reset();\n" +
"\t\tint w = input.width-1;\n" +
"\t\tint h = input.height-1;\n" +
"\n" +
"\t\t// First consider the inner pixels\n" +
"\t\tfor( int y = 0; y < h; y++ ) {\n" +
"\t\t\tint indexSrc = input.startIndex + y*input.stride + "+startX+";\n" +
"\t\t\tint indexDst = + y*input.width + "+startX+";\n" +
"\n" +
"\t\t\tfor( int x = "+startX+"; x < w; x++ , indexSrc++ , indexDst++ ) {\n" +
"\n" +
"\t\t\t\t"+sumType+" weight1=0,weight2=0"+weightString+";\n" +
"\n" +
"\t\t\t\tfor( int i = 0; i < numBands; i++ ) {\n" +
"\t\t\t\t\t"+imageName+" band = input.getBand(i);\n" +
"\n" +
"\t\t\t\t\t"+sumType+" color0 = band.data[indexSrc]"+bitwise+"; // (x,y)\n" +
"\t\t\t\t\t"+sumType+" color1 = band.data[indexSrc+1]"+bitwise+"; // (x+1,y)\n" +
"\t\t\t\t\t"+sumType+" color2 = band.data[indexSrc+input.stride]"+bitwise+"; // (x,y+1)\n" +
"\t\t\t\t\t"+sumType+" diff1 = color0-color1;\n" +
"\t\t\t\t\t"+sumType+" diff2 = color0-color2;\n" +
"\t\t\t\t\tweight1 += diff1*diff1;\n" +
"\t\t\t\t\tweight2 += diff2*diff2;\n");
if( rule == ConnectRule.EIGHT ) {
out.print(
"\t\t\t\t\t"+sumType+" color3 = band.data[indexSrc+1+input.stride]"+bitwise+"; // (x+1,y+1)\n" +
"\t\t\t\t\t"+sumType+" color4 = band.data[indexSrc-1+input.stride]"+bitwise+"; // (x-1,y+1)\n" +
"\t\t\t\t\t"+sumType+" diff3 = color0-color3;\n" +
"\t\t\t\t\t"+sumType+" diff4 = color0-color4;\n" +
"\t\t\t\t\tweight3 += diff3*diff3;\n" +
"\t\t\t\t\tweight4 += diff4*diff4;\n");
}
out.print(
"\t\t\t\t}\n" +
"\n" +
"\t\t\t\tEdge e1 = edges.grow();\n" +
"\t\t\t\tEdge e2 = edges.grow();\n" +
"\n" +
"\t\t\t\te1.sortValue = (float)Math.sqrt(weight1);\n" +
"\t\t\t\te1.indexA = indexDst;\n" +
"\t\t\t\te1.indexB = indexDst+1;\n" +
"\n" +
"\t\t\t\te2.sortValue = (float)Math.sqrt(weight2);\n" +
"\t\t\t\te2.indexA = indexDst;\n" +
"\t\t\t\te2.indexB = indexDst+input.width;\n" +
"\n");
if( rule == ConnectRule.EIGHT ) {
out.print(
"\t\t\t\tEdge e3 = edges.grow();\n" +
"\t\t\t\tEdge e4 = edges.grow();\n" +
"\n" +
"\t\t\t\te3.sortValue = (float)Math.sqrt(weight3);\n" +
"\t\t\t\te3.indexA = indexDst;\n" +
"\t\t\t\te3.indexB = indexDst+1+input.width;\n" +
"\n" +
"\t\t\t\te4.sortValue = (float)Math.sqrt(weight4);\n" +
"\t\t\t\te4.indexA = indexDst;\n" +
"\t\t\t\te4.indexB = indexDst-1+input.width;\n");
}
out.print(
"\t\t\t}\n" +
"\t\t}\n" +
"\n" +
"\t\t// Handle border pixels\n");
if( rule == ConnectRule.EIGHT ) {
out.print(
"\t\tfor( int y = 0; y < h; y++ ) {\n" +
"\t\t\tcheckAround(0,y,input,edges);\n" +
"\t\t\tcheckAround(w,y,input,edges);\n" +
"\t\t}\n" +
"\n" +
"\t\tfor( int x = 0; x < w; x++ ) {\n" +
"\t\t\tcheckAround(x,h,input,edges);\n" +
"\t\t}\n" +
"\t}\n\n");
} else {
out.print(
"\t\tfor( int y = 0; y < h; y++ ) {\n" +
"\t\t\tcheckAround(w,y,input,edges);\n" +
"\t\t}\n" +
"\n" +
"\t\tfor( int x = 0; x < w; x++ ) {\n" +
"\t\t\tcheckAround(x,h,input,edges);\n" +
"\t\t}\n" +
"\t}\n\n");
}
}
private void printCheckAround( AutoTypeImage imageType , ConnectRule rule ) {
String imageName = imageType.getSingleBandName();
String bitwise = imageType.getBitWise();
out.print("\tprivate void checkAround( int x , int y ,\n" +
"\t\t\t\t\t\t\t Planar<"+imageName+"> input ,\n" +
"\t\t\t\t\t\t\t FastQueue<Edge> edges )\n" +
"\t{\n" +
"\t\tint indexSrc = input.startIndex + y*input.stride + x;\n" +
"\t\tint indexA = y*input.width + x;\n" +
"\n" +
"\t\tfor( int i = 0; i < numBands; i++ ) {\n" +
"\t\t\t"+imageName+" band = input.getBand(i);\n" +
"\t\t\tpixelColor[i] = band.data[indexSrc]"+bitwise+";\n" +
"\t\t}\n" +
"\n" +
"\t\tcheck(x+1, y, pixelColor,indexA,input,edges);\n" +
"\t\tcheck(x ,y+1,pixelColor,indexA,input,edges);\n");
if( rule == ConnectRule.EIGHT ) {
out.print(
"\t\tcheck(x+1,y+1,pixelColor,indexA,input,edges);\n" +
"\t\tcheck(x-1,y+1,pixelColor,indexA,input,edges);\n");
}
out.print("\t}\n\n");
}
private void printCheck( AutoTypeImage imageType ) {
String imageName = imageType.getSingleBandName();
String sumType = imageType.getSumType();
String bitwise = imageType.getBitWise();
out.print("\tprivate void check( int x , int y , "+sumType+" color0[] , int indexA,\n" +
"\t\t\t\t\t\tPlanar<"+imageName+"> input ,\n" +
"\t\t\t\t\t\tFastQueue<Edge> edges ) {\n" +
"\t\tif( !input.isInBounds(x,y) )\n" +
"\t\t\treturn;\n" +
"\n" +
"\t\tint indexSrc = input.startIndex + y*input.stride + x;\n" +
"\t\tint indexB = + y*input.width + x;\n" +
"\n" +
"\t\tfloat weight = 0;\n" +
"\n" +
"\t\tfor( int i = 0; i < numBands; i++ ) {\n" +
"\t\t\t"+imageName+" band = input.getBand(i);\n" +
"\n" +
"\t\t\t"+sumType+" color = band.data[indexSrc]"+bitwise+";\n" +
"\t\t\t"+sumType+" diff = color0[i]-color;\n" +
"\t\t\tweight += diff*diff;\n" +
"\t\t}\n" +
"\n" +
"\t\tEdge e1 = edges.grow();\n" +
"\n" +
"\t\te1.sortValue = (float)Math.sqrt(weight);\n" +
"\t\te1.indexA = indexA;\n" +
"\t\te1.indexB = indexB;\n" +
"\t}\n\n");
}
private void printType( AutoTypeImage imageType ) {
String imageName = imageType.getSingleBandName();
out.print("\t@Override\n" +
"\tpublic ImageType<Planar<"+imageName+">> getInputType() {\n" +
"\t\treturn ImageType.pl(3,"+imageName+".class);\n" +
"\t}\n\n");
}
public static void main(String[] args) throws FileNotFoundException {
GenerateFhEdgeWeights_PL generator = new GenerateFhEdgeWeights_PL();
generator.generate();
}
}