void LocationSampler::sampleEquiDistant(cv::Rect ¤tLocation, std::vector<cv::Rect> &locations) { double centerX = currentLocation.x + currentLocation.width / 2; double centerY = currentLocation.y + currentLocation.height / 2; std::vector<double> radialValues = this->linspace(0, radius, nRadial + 1); std::vector<double> angularValues = this->linspace(0, 2 * M_PI, nAngular +1); int bb_x, bb_y = 0; cv::Rect imageBox(0, 0, this->n, this->m); int halfWidth = cvRound(currentLocation.width / 2.0); int halfHeight = cvRound(currentLocation.height / 2.0); for (int i = 1; i < radialValues.size(); ++i) { for (int j = 1; j < angularValues.size(); ++j) { // get the top left corner bb_x = centerX + (radialValues[i] * cos(angularValues[j])) - halfWidth; bb_y = centerY + (radialValues[i] * sin(angularValues[j])) - halfHeight; cv::Point topLeft(bb_x, bb_y); cv::Point bottomRight(bb_x + currentLocation.width, bb_y + currentLocation.height); if (imageBox.contains(topLeft) && imageBox.contains(bottomRight)) { cv::Rect rect(bb_x, bb_y, currentLocation.width, currentLocation.height); locations.push_back(rect); } } } }
Py::Object Image::resize(const Py::Tuple& args) { _VERBOSE("Image::resize"); args.verify_length(2); if (bufferIn ==NULL) throw Py::RuntimeError("You must first load the image"); int numcols = Py::Int(args[0]); int numrows = Py::Int(args[1]); colsOut = numcols; rowsOut = numrows; size_t NUMBYTES(numrows * numcols * BPP); agg::int8u *buffer = new agg::int8u[NUMBYTES]; if (buffer ==NULL) //todo: also handle allocation throw throw Py::MemoryError("Image::resize could not allocate memory"); rbufOut = new agg::rendering_buffer; rbufOut->attach(buffer, numcols, numrows, numcols * BPP); // init the output rendering/rasterizing stuff pixfmt pixf(*rbufOut); renderer_base rb(pixf); rb.clear(bg); agg::rasterizer_scanline_aa<> ras; agg::scanline_u8 sl; //srcMatrix *= resizingMatrix; //imageMatrix *= resizingMatrix; imageMatrix.invert(); interpolator_type interpolator(imageMatrix); agg::image_filter_base* filter = 0; agg::span_allocator<agg::rgba8> sa; agg::rgba8 background(agg::rgba8(int(255*bg.r), int(255*bg.g), int(255*bg.b), int(255*bg.a))); // the image path agg::path_storage path; agg::int8u *bufferPad = NULL; agg::rendering_buffer rbufPad; double x0, y0, x1, y1; if (interpolation==NEAREST) { x0 = 0.0; x1 = colsIn; y0 = 0.0; y1 = rowsIn; } else { // if interpolation != nearest, create a new input buffer with the // edges mirrored on all size. Then new buffer size is colsIn+2 by // rowsIn+2 x0 = 1.0; x1 = colsIn+1; y0 = 1.0; y1 = rowsIn+1; bufferPad = new agg::int8u[(rowsIn+2) * (colsIn+2) * BPP]; if (bufferPad ==NULL) throw Py::MemoryError("Image::resize could not allocate memory"); //pad the input buffer for (size_t rowNum=0; rowNum<rowsIn+2; rowNum++) for (size_t colNum=0; colNum<colsIn+2; colNum++) { if ( (colNum==0) && (rowNum==1||(rowNum==rowsIn+1))) { //rewind to begining of column bufferIn -= colsIn * BPP; } *bufferPad++ = *bufferIn++; //red *bufferPad++ = *bufferIn++; //green *bufferPad++ = *bufferIn++; //blue *bufferPad++ = *bufferIn++; //alpha //rewind one byte on the first and next to last columns if ( colNum==0 || colNum==colsIn) bufferIn-=4; } //rewind the input buffers bufferIn -= rowsIn * colsIn * BPP; bufferPad -= (rowsIn+2) * (colsIn+2) * BPP; rbufPad.attach(bufferPad, colsIn+2, rowsIn+2, (colsIn+2) * BPP); } if (buffer ==NULL) //todo: also handle allocation throw throw Py::MemoryError("Image::resize could not allocate memory"); path.move_to(x0, y0); path.line_to(x1, y0); path.line_to(x1, y1); path.line_to(x0, y1); path.close_polygon(); agg::conv_transform<agg::path_storage> imageBox(path, srcMatrix); ras.add_path(imageBox); switch(interpolation) { case NEAREST: { typedef agg::span_image_filter_rgba32_nn<agg::order_rgba32, interpolator_type> span_gen_type; typedef agg::renderer_scanline_aa<renderer_base, span_gen_type> renderer_type; span_gen_type sg(sa, *rbufIn, background, interpolator); renderer_type ri(rb, sg); agg::render_scanlines(ras, sl, ri); } break; case BILINEAR: { typedef agg::span_image_filter_rgba32_bilinear<agg::order_rgba32, interpolator_type> span_gen_type; typedef agg::renderer_scanline_aa<renderer_base, span_gen_type> renderer_type; span_gen_type sg(sa, rbufPad, background, interpolator); renderer_type ri(rb, sg); agg::render_scanlines(ras, sl, ri); } break; case BICUBIC: filter = new agg::image_filter<agg::image_filter_bicubic>; case SPLINE16: filter = new agg::image_filter<agg::image_filter_spline16>; case SPLINE36: filter = new agg::image_filter<agg::image_filter_spline36>; case SINC64: filter = new agg::image_filter<agg::image_filter_sinc64>; case SINC144: filter = new agg::image_filter<agg::image_filter_sinc144>; case SINC256: filter = new agg::image_filter<agg::image_filter_sinc256>; case BLACKMAN64: filter = new agg::image_filter<agg::image_filter_blackman64>; case BLACKMAN100: filter = new agg::image_filter<agg::image_filter_blackman100>; case BLACKMAN256: filter = new agg::image_filter<agg::image_filter_blackman256>; typedef agg::span_image_filter_rgba32<agg::order_rgba32, interpolator_type> span_gen_type; typedef agg::renderer_scanline_aa<renderer_base, span_gen_type> renderer_type; span_gen_type sg(sa, rbufPad, background, interpolator, *filter); renderer_type ri(rb, sg); agg::render_scanlines(ras, sl, ri); } /* std::ofstream of2( "image_out.raw", std::ios::binary|std::ios::out); for (size_t i=0; i<NUMBYTES; ++i) of2.write((char*)&buffer[i], sizeof(char)); */ bufferOut = buffer; delete [] bufferPad; return Py::Object(); }
Py::Object Image::resize(const Py::Tuple& args) { _VERBOSE("Image::resize"); args.verify_length(2); if (bufferIn ==NULL) throw Py::RuntimeError("You must first load the image"); int numcols = Py::Int(args[0]); int numrows = Py::Int(args[1]); colsOut = numcols; rowsOut = numrows; size_t NUMBYTES(numrows * numcols * BPP); agg::int8u *buffer = new agg::int8u[NUMBYTES]; if (buffer ==NULL) //todo: also handle allocation throw throw Py::MemoryError("Image::resize could not allocate memory"); rbufOut = new agg::rendering_buffer; rbufOut->attach(buffer, numcols, numrows, numcols * BPP); // init the output rendering/rasterizing stuff pixfmt pixf(*rbufOut); renderer_base rb(pixf); rb.clear(bg); agg::rasterizer_scanline_aa<> ras; agg::scanline_u8 sl; //srcMatrix *= resizingMatrix; //imageMatrix *= resizingMatrix; imageMatrix.invert(); interpolator_type interpolator(imageMatrix); // the image path agg::path_storage path; path.move_to(0, 0); path.line_to(colsIn, 0); path.line_to(colsIn, rowsIn); path.line_to(0, rowsIn); path.close_polygon(); agg::conv_transform<agg::path_storage> imageBox(path, srcMatrix); ras.add_path(imageBox); agg::image_filter_base* filter = 0; agg::span_allocator<agg::rgba8> sa; switch(interpolation) { case NEAREST: { typedef agg::span_image_filter_rgba32_nn<agg::order_rgba32, interpolator_type> span_gen_type; typedef agg::renderer_scanline_u<renderer_base, span_gen_type> renderer_type; span_gen_type sg(sa, *rbufIn, agg::rgba(1,1,1,0), interpolator); renderer_type ri(rb, sg); ras.add_path(imageBox); ras.render(sl, ri); } break; case BILINEAR: { typedef agg::span_image_filter_rgba32_bilinear<agg::order_rgba32, interpolator_type> span_gen_type; typedef agg::renderer_scanline_u<renderer_base, span_gen_type> renderer_type; span_gen_type sg(sa, *rbufIn, agg::rgba(1,1,1,0), interpolator); renderer_type ri(rb, sg); ras.add_path(imageBox); ras.render(sl, ri); } break; case BICUBIC: filter = new agg::image_filter<agg::image_filter_bicubic>; case SPLINE16: filter = new agg::image_filter<agg::image_filter_spline16>; case SPLINE36: filter = new agg::image_filter<agg::image_filter_spline36>; case SINC64: filter = new agg::image_filter<agg::image_filter_sinc64>; case SINC144: filter = new agg::image_filter<agg::image_filter_sinc144>; case SINC256: filter = new agg::image_filter<agg::image_filter_sinc256>; case BLACKMAN64: filter = new agg::image_filter<agg::image_filter_blackman64>; case BLACKMAN100: filter = new agg::image_filter<agg::image_filter_blackman100>; case BLACKMAN256: filter = new agg::image_filter<agg::image_filter_blackman256>; typedef agg::span_image_filter_rgba32<agg::order_rgba32, interpolator_type> span_gen_type; typedef agg::renderer_scanline_u<renderer_base, span_gen_type> renderer_type; span_gen_type sg(sa, *rbufIn, agg::rgba(1,1,1,0), interpolator, *filter); renderer_type ri(rb, sg); ras.render(sl, ri); } /* std::ofstream of2( "image_out.raw", std::ios::binary|std::ios::out); for (size_t i=0; i<NUMBYTES; ++i) of2.write((char*)&buffer[i], sizeof(char)); */ bufferOut = buffer; return Py::Object(); }
/** * Samples rectangles in polar coordinates * * @param currentLocation current bounding box * @param locations vector of sampled bounding boxes */ void LocationSampler::sampleEquiDistantMultiScale( cv::Rect ¤tLocation, std::vector<cv::Rect> &locations) { double centerX = currentLocation.x + currentLocation.width / 2; double centerY = currentLocation.y + currentLocation.height / 2; std::vector<double> radialValues = this->linspace(0, radius, nRadial + 1); std::vector<double> angularValues = this->linspace(0, 2 * M_PI, nAngular +1); int bb_x, bb_y = 0; cv::Rect imageBox(0, 0, this->n, this->m); int halfWidth = cvRound(currentLocation.width / 2.0); int halfHeight = cvRound(currentLocation.height / 2.0); for (int i = 1; i < radialValues.size(); ++i) { for (int j = 1; j < angularValues.size(); ++j) { // get the top left corner bb_x = centerX + (radialValues[i] * cos(angularValues[j])) - halfWidth; bb_y = centerY + (radialValues[i] * sin(angularValues[j])) - halfHeight; cv::Point topLeft(bb_x, bb_y); cv::Point bottomRight(bb_x + currentLocation.width, bb_y + currentLocation.height); if (imageBox.contains(topLeft) && imageBox.contains(bottomRight)) { cv::Rect rect(bb_x, bb_y, currentLocation.width, currentLocation.height); locations.push_back(rect); } } } // auto div = [](double x, double y) {return x/y;}; int scaleR = this->radius; // halfWidth=cvRound(this->objectWidth/2.0); // halfHeight=cvRound(this->objectHeight/2.0); // halfWidth=cvRound(currentLocation.width/2.0); // halfHeight=cvRound(currentLocation.height/2.0); double downsample = 1.05; radialValues = this->linspace(0, scaleR, nRadial / 3 + 1); angularValues = this->linspace(0, 2 * M_PI, nAngular / 3 + 1); // radialValues=arma::linspace<arma::vec>(0,scaleR,3); // angularValues=arma::linspace<arma::vec>(0,2*M_PI, 3); int scale = 8; int shrinkOneSideScale = 2; // return; std::vector<int> scale_half_width; std::vector<int> scale_half_height; // for (int scale_w=-MIN(2, scale); scale_w<=scale; scale_w++) { double downsample_2 = 1.05; for (int scale_h = -shrinkOneSideScale + 1; scale_h <= shrinkOneSideScale; scale_h++) { int scale_w = scale_h; for (int scale_w = -shrinkOneSideScale + 1; scale_w <= shrinkOneSideScale; scale_w++) { // continue; if ((scale_w == 0 && scale_h == 0)) { continue; } int halfWidth_scale = cvRound(halfWidth * pow(downsample_2, scale_w)); int halfHeight_scale = cvRound(halfHeight * pow(downsample_2, scale_h)); if (halfWidth_scale <= 10 || halfHeight_scale <= 10) { continue; } scale_half_width.push_back(halfWidth_scale); scale_half_height.push_back(halfHeight_scale); } } for (int scale_h = -scale + 5; scale_h <= scale; scale_h++) { int scale_w = scale_h; if (scale_w == 0 && scale_h == 0) { continue; } int halfWidth_scale = cvRound((this->objectWidth / 2.0) * pow(downsample, scale_w)); int halfHeight_scale = cvRound((this->objectHeight / 2.0) * pow(downsample, scale_h)); if (halfWidth_scale <= 10 || halfHeight_scale <= 10) { continue; } scale_half_width.push_back(halfWidth_scale); scale_half_height.push_back(halfHeight_scale); } for (int s = 0; s < scale_half_width.size(); s++) { int width_scale = scale_half_width[s] * 2; int height_scale = scale_half_height[s] * 2; // double widthRatio=((double)width_scale)/this->objectWidth; // double heightRatio=((double)height_scale)/this->objectHeight; // if (widthRatio<=0.6 || heightRatio<=0.6) { // continue; // } // if // (std::abs(div(width_scale,height_scale)-div(this->objectWidth,this->objectHeight))*(div(height_scale,width_scale)-div(this->objectHeight,this->objectWidth))>1) // { // continue; // } for (int i = 0; i < radialValues.size(); ++i) { for (int j = 0; j < angularValues.size(); ++j) { // get the top left corner bb_x = centerX + (radialValues[i] * cos(angularValues[j])) - scale_half_width[s]; bb_y = centerY + (radialValues[i] * sin(angularValues[j])) - scale_half_height[s]; cv::Point topLeft(bb_x, bb_y); cv::Point bottomRight(bb_x + width_scale, bb_y + height_scale); if (imageBox.contains(topLeft) && imageBox.contains(bottomRight)) { cv::Rect rect(bb_x, bb_y, width_scale, height_scale); locations.push_back(rect); } } // } } } }
/** * Sample on a grid * * @param currentLocation current location * @param locations vector with locations * @param R radius vector to use for sampling * @param step how spread should locations be, default=1 */ void LocationSampler::sampleOnAGrid(cv::Rect ¤tLocation, std::vector<cv::Rect> &locations, int R, int step) { int centerX = cvRound(currentLocation.x + currentLocation.width / 2.0); int centerY = cvRound(currentLocation.y + currentLocation.height / 2.0); int halfWidth = cvRound(currentLocation.width / 2.0); int halfHeight = cvRound(currentLocation.height / 2.0); cv::Rect imageBox(0, 0, this->n, this->m); for (int x = -R; x <= R; x = x + step) { for (int y = -R; y <= R; y = y + step) { // make sure everything is within the radius if (sqrt(pow(x, 2) + pow(y, 2)) > R) { continue; } // get the top left corner int bb_x = centerX + x - halfWidth; int bb_y = centerY + y - halfHeight; cv::Point topLeft(bb_x, bb_y); cv::Point bottomRight(bb_x + currentLocation.width, bb_y + currentLocation.height); if (imageBox.contains(topLeft) && imageBox.contains(bottomRight)) { cv::Rect rect(bb_x, bb_y, currentLocation.width, currentLocation.height); locations.push_back(rect); } } } int scaleR = R / 6; double downsample = 1.05; for (int scale_w = -2; scale_w <= 2; scale_w++) { for (int scale_h = -2; scale_h <= 2; scale_h++) { if (scale_w == 0 && scale_h == 0) { continue; } int halfWidth_scale = cvRound(halfWidth * pow(downsample, scale_w)); int halfHeight_scale = cvRound(halfHeight * pow(downsample, scale_h)); int width_scale = halfWidth_scale * 2; int height_scale = halfHeight_scale * 2; for (int x = -scaleR; x <= scaleR; x = x + step) { for (int y = -scaleR; y <= scaleR; y = y + step) { // make sure everything is within the radius if (sqrt(pow(x, 2) + pow(y, 2)) > scaleR) { continue; } // get the top left corner int bb_x = centerX + x - halfWidth_scale; int bb_y = centerY + y - halfHeight_scale; cv::Point topLeft(bb_x, bb_y); cv::Point bottomRight(bb_x + width_scale, bb_y + height_scale); if (imageBox.contains(topLeft) && imageBox.contains(bottomRight)) { cv::Rect rect(bb_x, bb_y, width_scale, height_scale); locations.push_back(rect); } } } } } }
Py::Object Image::resize(const Py::Tuple& args, const Py::Dict& kwargs) { _VERBOSE("Image::resize"); args.verify_length(2); int norm = 1; if ( kwargs.hasKey("norm") ) norm = Py::Int( kwargs["norm"] ); double radius = 4.0; if ( kwargs.hasKey("radius") ) radius = Py::Float( kwargs["radius"] ); if (bufferIn ==NULL) throw Py::RuntimeError("You must first load the image"); int numcols = Py::Int(args[0]); int numrows = Py::Int(args[1]); colsOut = numcols; rowsOut = numrows; size_t NUMBYTES(numrows * numcols * BPP); delete [] bufferOut; bufferOut = new agg::int8u[NUMBYTES]; if (bufferOut ==NULL) //todo: also handle allocation throw throw Py::MemoryError("Image::resize could not allocate memory"); delete rbufOut; rbufOut = new agg::rendering_buffer; rbufOut->attach(bufferOut, numcols, numrows, numcols * BPP); // init the output rendering/rasterizing stuff pixfmt pixf(*rbufOut); renderer_base rb(pixf); rb.clear(bg); agg::rasterizer_scanline_aa<> ras; agg::scanline_u8 sl; //srcMatrix *= resizingMatrix; //imageMatrix *= resizingMatrix; imageMatrix.invert(); interpolator_type interpolator(imageMatrix); typedef agg::span_allocator<agg::rgba8> span_alloc_type; span_alloc_type sa; agg::rgba8 background(agg::rgba8(int(255*bg.r), int(255*bg.g), int(255*bg.b), int(255*bg.a))); // the image path agg::path_storage path; agg::int8u *bufferPad = NULL; agg::rendering_buffer rbufPad; double x0, y0, x1, y1; x0 = 0.0; x1 = colsIn; y0 = 0.0; y1 = rowsIn; path.move_to(x0, y0); path.line_to(x1, y0); path.line_to(x1, y1); path.line_to(x0, y1); path.close_polygon(); agg::conv_transform<agg::path_storage> imageBox(path, srcMatrix); ras.add_path(imageBox); typedef agg::wrap_mode_reflect reflect_type; typedef agg::image_accessor_wrap<pixfmt, reflect_type, reflect_type> img_accessor_type; pixfmt pixfmtin(*rbufIn); img_accessor_type ia(pixfmtin); switch(interpolation) { case NEAREST: { typedef agg::span_image_filter_rgba_nn<img_accessor_type, interpolator_type> span_gen_type; typedef agg::renderer_scanline_aa<renderer_base, span_alloc_type, span_gen_type> renderer_type; span_gen_type sg(ia, interpolator); renderer_type ri(rb, sa, sg); agg::render_scanlines(ras, sl, ri); } break; case BILINEAR: case BICUBIC: case SPLINE16: case SPLINE36: case HANNING: case HAMMING: case HERMITE: case KAISER: case QUADRIC: case CATROM: case GAUSSIAN: case BESSEL: case MITCHELL: case SINC: case LANCZOS: case BLACKMAN: { agg::image_filter_lut filter; switch(interpolation) { case BILINEAR: filter.calculate(agg::image_filter_bilinear(), norm); break; case BICUBIC: filter.calculate(agg::image_filter_bicubic(), norm); break; case SPLINE16: filter.calculate(agg::image_filter_spline16(), norm); break; case SPLINE36: filter.calculate(agg::image_filter_spline36(), norm); break; case HANNING: filter.calculate(agg::image_filter_hanning(), norm); break; case HAMMING: filter.calculate(agg::image_filter_hamming(), norm); break; case HERMITE: filter.calculate(agg::image_filter_hermite(), norm); break; case KAISER: filter.calculate(agg::image_filter_kaiser(), norm); break; case QUADRIC: filter.calculate(agg::image_filter_quadric(), norm); break; case CATROM: filter.calculate(agg::image_filter_catrom(), norm); break; case GAUSSIAN: filter.calculate(agg::image_filter_gaussian(), norm); break; case BESSEL: filter.calculate(agg::image_filter_bessel(), norm); break; case MITCHELL: filter.calculate(agg::image_filter_mitchell(), norm); break; case SINC: filter.calculate(agg::image_filter_sinc(radius), norm); break; case LANCZOS: filter.calculate(agg::image_filter_lanczos(radius), norm); break; case BLACKMAN: filter.calculate(agg::image_filter_blackman(radius), norm); break; } typedef agg::span_image_filter_rgba_2x2<img_accessor_type, interpolator_type> span_gen_type; typedef agg::renderer_scanline_aa<renderer_base, span_alloc_type, span_gen_type> renderer_type; span_gen_type sg(ia, interpolator, filter); renderer_type ri(rb, sa, sg); agg::render_scanlines(ras, sl, ri); } break; } delete [] bufferPad; return Py::Object(); }