// Map [u,v] of range [0,1] to [width, height] // Does bilinear interpolation. Also clamps Colour imgTexture::getColour(const Point2D& uv) { const int width = m_image.width(); const int height = m_image.height(); // // u = abs(u); // v = abs(v); // clamp u,v to [0,1]. Interpolate between two points int umin = int(width * uv.v_[0]); int umax = int(width * uv.v_[0]) + 1; int vmin = int(height * uv.v_[1]); int vmax = int(height * uv.v_[1]) + 1; umin = std::min(std::max(umin, 0), width -1 ); umax = std::min(std::max(umax, 0), width -1 ); vmin = std::min(std::max(vmin, 0), height-1); vmax = std::min(std::max(vmax, 0), height - 1); // 4 samples on square Colour p0 = m_image(umin, vmin); Colour p1 = m_image(umin, vmax); Colour p2 = m_image(umax, vmin); Colour p3 = m_image(umax, vmax); double uD = width * uv.v_[0] - umin; double vD = height* uv.v_[1] - vmin; //4 point interpolation Colour finalColour = vD * (uD * p0 + (1.0 - uD) * p1) + // top points (1.0 - vD) * (uD * p2 + (1.0 - uD) * p3);//bottom points return finalColour; }
void FrequencyPlot::update(int w, int h) { m_image.load(w, h, 1); m_rect = {10, 10, (w | 1) - 40, (h | 1) - 20}; m_width_rcp = 1.0f / float(m_rect.width()); fill(&m_image, Color(0)); for(int x=0; x<m_rect.width(); x++) { if(!(x & 1)) { int xx = x + m_rect.x(); m_image(xx, m_rect.y())[0] = m_image(xx, m_rect.bottom() - 1)[0] = 255; } } float maxfreqlog = log10(maxFreq()); m_min_freq_log = log10(minFreq()); m_freq_range_log = maxfreqlog - m_min_freq_log; m_freq_range_log_rcp = 1.0f / m_freq_range_log; int n = 1; float f = 1.0f; float df = 1.0f; for(;;) { if(f >= minFreq()) { if(f >= maxFreq()) break; int x = (log10(f) - m_min_freq_log) * m_freq_range_log_rcp * m_rect.width(); paintLineAt(x + m_rect.x(), n == 1 ? 127 : 63); } n++; f += df; if(n == 10) { n = 1; df *= 10; } } paintLineAt(m_rect.x(), 255); paintLineAt(m_rect.right()-1, 255); }
void FrequencyPlot::paintLineAt(int x, unsigned char value) { for(int y=2; y<m_rect.height()-2; y++) { if(!(y & 1)) { int yy = y + m_rect.y(); m_image(x, yy)[0] = value; } } }
void flannFindPairs( const CvSeq*, const CvSeq* objectDescriptors, const CvSeq*, const CvSeq* imageDescriptors, vector<int>& ptpairs ) { int length = (int)(objectDescriptors->elem_size/sizeof(float)); cv::Mat m_object(objectDescriptors->total, length, CV_32F); cv::Mat m_image(imageDescriptors->total, length, CV_32F); // copy descriptors CvSeqReader obj_reader; float* obj_ptr = m_object.ptr<float>(0); cvStartReadSeq( objectDescriptors, &obj_reader ); for(int i = 0; i < objectDescriptors->total; i++ ) { const float* descriptor = (const float*)obj_reader.ptr; CV_NEXT_SEQ_ELEM( obj_reader.seq->elem_size, obj_reader ); memcpy(obj_ptr, descriptor, length*sizeof(float)); obj_ptr += length; } CvSeqReader img_reader; float* img_ptr = m_image.ptr<float>(0); cvStartReadSeq( imageDescriptors, &img_reader ); for(int i = 0; i < imageDescriptors->total; i++ ) { const float* descriptor = (const float*)img_reader.ptr; CV_NEXT_SEQ_ELEM( img_reader.seq->elem_size, img_reader ); memcpy(img_ptr, descriptor, length*sizeof(float)); img_ptr += length; } // find nearest neighbors using FLANN cv::Mat m_indices(objectDescriptors->total, 2, CV_32S); cv::Mat m_dists(objectDescriptors->total, 2, CV_32F); cv::flann::Index flann_index(m_image, cv::flann::KDTreeIndexParams(4)); // using 4 randomized kdtrees flann_index.knnSearch(m_object, m_indices, m_dists, 2, cv::flann::SearchParams(64) ); // maximum number of leafs checked int* indices_ptr = m_indices.ptr<int>(0); float* dists_ptr = m_dists.ptr<float>(0); for (int i=0;i<m_indices.rows;++i) { if (dists_ptr[2*i]<0.6*dists_ptr[2*i+1]) { ptpairs.push_back(i); ptpairs.push_back(indices_ptr[2*i]); } } }
Image Image::crop(int x1, int y1, int x2, int y2) { try { cv::Point tl(x1,y1); cv::Point br(x2,y2); cv::Rect rectangle(tl,br); Image cropped; cropped.setImage(m_image(rectangle)); return cropped; } catch(cv::Exception & ex) { throw OpenCVException(ex.msg.c_str()); } }