void _validate(bool)
 {
   filter.initialize();
   copy_info();
 }
예제 #2
0
// Here we need to expand the image and the bounding box. This is the most important method in a plug like this so
// pay attention
void SyLens::_validate(bool for_real)
{
	// Bookkeeping boilerplate
	filter.initialize();
	input0().validate(for_real);
	copy_info();
	set_out_channels(Mask_All);
	
	// Do not blank away everything
	info_.black_outside(false);
	
	// We need to know our aspects so prep them here
	_computeAspects();
	
	distorter.set_aspect(_aspect);
	distorter.recompute_if_needed();
	
	if(k_enable_debug_) printf("SyLens: _validate info box to  %dx%d\n", plate_width_, plate_height_);
	
	// Time to define how big our output will be in terms of format. Format will always be the whole plate.
	// If we only use a bboxed piece of the image we will limit our request to that. But first of all we need to
	// compute the format of our output.
	int ow, oh;
	
	ow = plate_width_;
	oh = plate_height_;
	
	// Nudge outputs to power of 2, upwards
	if(ow % 2 != 0) ow +=1;
	if(oh % 2 != 0) oh +=1;
	
	// For the case when we are working with a 8k by 4k plate with a SMALL CG pink elephant rrright in the left
	// corner we want to actually translate the bbox of the elephant to our distorted pipe downstream. So we need to
	// apply our SuperAlgorizm to the bbox as well and move the bbox downstream too.
	// Grab the bbox from the input first
	Info inf = input0().info();
	Format f = input0().format();
	
	// Just distorting the four corners of the bbox is NOT enough. We also need to find out whether
	// the bbox intersects the centerlines. Since the distortion is the most extreme at the centerlines if
	// we just take the corners we might be chopping some image away. So to get a reliable bbox we need to check
	// our padding at 6 points - the 4 extremes and where the bbox crosses the middle of the coordinates
	int xMid = ow/2;
	int yMid = oh/2;

	std::vector<Vector2*> pointsOnBbox;
	
	// Add the standard two points - LR and TR
	pointsOnBbox.push_back(new Vector2(inf.x(), inf.y()));
	pointsOnBbox.push_back(new Vector2(inf.r(), inf.t()));
	
	// Add the TL and LR as well
	pointsOnBbox.push_back(new Vector2(inf.x(), inf.t()));
	pointsOnBbox.push_back(new Vector2(inf.r(), inf.y()));
	
	// If our box intersects the midplane on X add the points where the bbox crosses centerline
	if((inf.x() < xMid) && (inf.r() > xMid)) {
		// Find the two intersections and add them
		pointsOnBbox.push_back( new Vector2(xMid, inf.y()) );
		pointsOnBbox.push_back( new Vector2(xMid, inf.t()) );
	}
	
	// If our box intersects the midplane on Y add the points where the bbox crosses centerline
	if((inf.y() < yMid) && (inf.t() > yMid)) {
		pointsOnBbox.push_back( new Vector2(inf.x(), yMid) );
		pointsOnBbox.push_back( new Vector2(inf.r(), yMid) );
	}
	
	std::vector<int> xValues;
	std::vector<int> yValues;
	
	// Here the distortion is INVERTED with relation to the pixel operation. With pixels, we need
	// to obtain the coordinate to sample FROM. However, here we need a coordinate to sample TO
	// since this is where our bbox corners are going to be in the coordinate plane of the output
	// format.
	for(unsigned int i = 0; i < pointsOnBbox.size(); i++) {
		if(kMode == UNDIST) {
			undistort_px_into_destination(*pointsOnBbox[i]);
		} else {
			distort_px_into_source(*pointsOnBbox[i]);
		}
		xValues.push_back(pointsOnBbox[i]->x);
		yValues.push_back(pointsOnBbox[i]->y);
	}
	
	int minX, minY, maxX, maxY;
	
	// Formally speaking, we have to allocate an std::iterator first. But we wont.
	minX = *std::min_element(xValues.begin(), xValues.end());
	maxX = *std::max_element(xValues.begin(), xValues.end());
	minY = *std::min_element(yValues.begin(), yValues.end());
	maxY = *std::max_element(yValues.begin(), yValues.end());
	
	Box obox(minX, minY, maxX, maxY);
	
	// If trim is enabled we intersect our obox with the format so that there is no bounding box
	// outside the crop area. Thiis handy for redistorted material.
	if(k_trim_bbox_to_format_) obox.intersect(input0().format());
	
	if(k_enable_debug_) printf("SyLens: output bbox is %dx%d to %dx%d\n", obox.x(), obox.y(), obox.r(), obox.t());
	
	info_.set(obox);
}