void _validate(bool) { filter.initialize(); copy_info(); }
// 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); }