/*
* 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.abst.tracker;
import boofcv.abst.distort.FDistort;
import boofcv.alg.misc.GImageMiscOps;
import boofcv.struct.image.GrayU8;
import boofcv.struct.image.ImageDataType;
import boofcv.struct.image.ImageType;
import boofcv.struct.image.Planar;
import georegression.struct.point.Point2D_F64;
import georegression.struct.shapes.Polygon2D_I32;
import georegression.struct.shapes.Quadrilateral_F64;
/**
* Tests for trackers which use color information alone to track an object
*
* @author Peter Abeles
*/
public abstract class ColorTrackerObjectRectangleTests extends GenericTrackerObjectRectangleTests<Planar<GrayU8>> {
Planar<GrayU8> original = new Planar<>(GrayU8.class,width,height,3);
boolean multiColor;
public ColorTrackerObjectRectangleTests( boolean multiColor ) {
super(new ImageType<Planar<GrayU8>>(ImageType.Family.PLANAR, ImageDataType.U8,3));
this.multiColor = multiColor;
input = new Planar<>(GrayU8.class,width,height,3);
}
@Override
protected void render( double scale , double tranX , double tranY ) {
// each region in the target region will have a different color. Allowing scale, translation, and rotation
// to be estimated using color information alone
Quadrilateral_F64 q = initRegion.copy();
// scale it down a bit so that there is a border
if( multiColor )
scale(q,0.95);
Point2D_F64 ab = average(q.a,q.b);
Point2D_F64 bc = average(q.b,q.c);
Point2D_F64 cd = average(q.c,q.d);
Point2D_F64 da = average(q.d,q.a);
Point2D_F64 abcd = average(ab,cd);
Quadrilateral_F64 r0 = new Quadrilateral_F64(q.a,ab,abcd,da,true);
Quadrilateral_F64 r1 = new Quadrilateral_F64(ab,q.b,bc,abcd,true);
Quadrilateral_F64 r2 = new Quadrilateral_F64(abcd,bc,q.c,cd,true);
Quadrilateral_F64 r3 = new Quadrilateral_F64(da,abcd,cd,q.d,true);
Polygon2D_I32 region[] = new Polygon2D_I32[4];
region[0] = setPolygon(r0);
region[1] = setPolygon(r1);
region[2] = setPolygon(r2);
region[3] = setPolygon(r3);
int band0[] = new int[]{100,50,176,0};
int band1[] = new int[]{150,200,240,40};
int band2[] = new int[]{20,234,176,210};
GImageMiscOps.fill(original,0);
GImageMiscOps.fill(input,0);
for( int i = 0; i < 4; i++ ) {
int colorIndex;
if( multiColor )
colorIndex = i;
else
colorIndex = 0;
TextureGrayTrackerObjectRectangleTests.convexFill(region[i],original.getBand(0),band0[colorIndex]);
TextureGrayTrackerObjectRectangleTests.convexFill(region[i],original.getBand(1),band1[colorIndex]);
TextureGrayTrackerObjectRectangleTests.convexFill(region[i],original.getBand(2),band2[colorIndex]);
}
new FDistort(original,input).affine(scale,0,0,scale,tranX,tranY).apply();
}
private Point2D_F64 average( Point2D_F64 a , Point2D_F64 b ) {
return new Point2D_F64((a.x+b.x)/2.0,(a.y+b.y)/2.0);
}
private Polygon2D_I32 setPolygon( Quadrilateral_F64 q ) {
q = q.copy();
Polygon2D_I32 p = new Polygon2D_I32(4);
p.vertexes.data[0].set((int)q.a.x,(int)q.a.y);
p.vertexes.data[1].set((int)q.b.x,(int)q.b.y);
p.vertexes.data[2].set((int)q.c.x,(int)q.c.y);
p.vertexes.data[3].set((int)q.d.x,(int)q.d.y);
return p;
}
private void scale( Quadrilateral_F64 q , double scale ) {
Point2D_F64 center0 = average(average(q.a, q.b), average(q.c, q.d));
q.a.x *= scale;
q.a.y *= scale;
q.b.x *= scale;
q.b.y *= scale;
q.c.x *= scale;
q.c.y *= scale;
q.d.x *= scale;
q.d.y *= scale;
Point2D_F64 center1 = average(average(q.a,q.b),average(q.c,q.d));
q.a.x += center1.x - center0.x;
q.a.y += center1.x - center0.x;
q.b.x += center1.x - center0.x;
q.b.y += center1.x - center0.x;
q.c.x += center1.x - center0.x;
q.c.y += center1.x - center0.x;
q.d.x += center1.x - center0.x;
q.d.y += center1.x - center0.x;
}
}