void StereoVar::operator ()( const Mat& left, const Mat& right, Mat& disp ) { CV_Assert(left.size() == right.size() && left.type() == right.type()); CvSize imgSize = left.size(); int MaxD = MAX(labs(minDisp), labs(maxDisp)); int SignD = 1; if (MIN(minDisp, maxDisp) < 0) SignD = -1; if (minDisp >= maxDisp) {MaxD = 256; SignD = 1;} Mat u; if ((flags & USE_INITIAL_DISPARITY) && (!disp.empty())) { CV_Assert(disp.size() == left.size() && disp.type() == CV_8UC1); disp.convertTo(u, CV_32FC1, static_cast<double>(SignD * MaxD) / 256); } else { u.create(imgSize, CV_32FC1); u.setTo(0); } // Preprocessing Mat leftgray, rightgray; if (left.type() != CV_8UC1) { cvtColor(left, leftgray, CV_BGR2GRAY); cvtColor(right, rightgray, CV_BGR2GRAY); } else { left.copyTo(leftgray); right.copyTo(rightgray); } if (flags & USE_EQUALIZE_HIST) { equalizeHist(leftgray, leftgray); equalizeHist(rightgray, rightgray); } if (poly_sigma > 0.0001) { GaussianBlur(leftgray, leftgray, cvSize(poly_n, poly_n), poly_sigma); GaussianBlur(rightgray, rightgray, cvSize(poly_n, poly_n), poly_sigma); } if (flags & USE_AUTO_PARAMS) { penalization = PENALIZATION_TICHONOV; autoParams(); } Mat I1, I2; leftgray.convertTo(I1, CV_32FC1); rightgray.convertTo(I2, CV_32FC1); leftgray.release(); rightgray.release(); Mat I2x = diffX(I2); FMG(I1, I2, I2x, u, levels - 1); I1.release(); I2.release(); I2x.release(); disp.create( left.size(), CV_8UC1 ); u = abs(u); u.convertTo(disp, disp.type(), 256 / MaxD, 0); u.release(); }
bool writeConfigurationToFile(const String& options, std::vector<char>& buf) { if (hash_ == NULL) return true; // don't save programs without hash if (!f.is_open()) { f.open(fileName_.c_str(), std::ios::in|std::ios::out|std::ios::binary); if (!f.is_open()) { f.open(fileName_.c_str(), std::ios::out|std::ios::binary); if (!f.is_open()) return false; } } f.seekg(0, std::fstream::end); size_t fileSize = (size_t)f.tellg(); if (fileSize == 0) { f.seekp(0, std::fstream::beg); int hashLength = strlen(hash_); f.write((char*)&hashLength, sizeof(int)); f.write(hash_, hashLength); int numberOfEntries = MAX_ENTRIES; f.write((char*)&numberOfEntries, sizeof(int)); std::vector<int> firstEntryOffset(MAX_ENTRIES, 0); f.write((char*)&firstEntryOffset[0], sizeof(int)*numberOfEntries); f.close(); f.open(fileName_.c_str(), std::ios::in|std::ios::out|std::ios::binary); CV_Assert(f.is_open()); f.seekg(0, std::fstream::end); fileSize = (size_t)f.tellg(); } f.seekg(0, std::fstream::beg); int hashLength = 0; f.read((char*)&hashLength, sizeof(int)); CV_Assert(hashLength > 0); f.seekg(sizeof(hashLength) + hashLength, std::fstream::beg); int numberOfEntries = 0; f.read((char*)&numberOfEntries, sizeof(int)); CV_Assert(numberOfEntries > 0); if (numberOfEntries != MAX_ENTRIES) { std::cerr << "Invalid file: " << fileName_ << std::endl; f.close(); remove(fileName_.c_str()); return false; } size_t tableEntriesOffset = (size_t)f.tellg(); std::vector<int> firstEntryOffset(numberOfEntries); f.read((char*)&firstEntryOffset[0], sizeof(int)*numberOfEntries); int entryNum = getHash(options); int entryOffset = firstEntryOffset[entryNum]; ProgramFileConfigurationEntry entry; while (entryOffset > 0) { f.seekg(entryOffset, std::fstream::beg); assert(sizeof(entry) == sizeof(int)*3); f.read((char*)&entry, sizeof(entry)); std::vector<char> foptions(entry.optionsLength); if ((int)options.length() == entry.optionsLength) { if (entry.optionsLength > 0) f.read(&foptions[0], entry.optionsLength); CV_Assert(memcmp(&foptions, options.c_str(), entry.optionsLength) != 0); } if (entry.nextEntry <= 0) break; entryOffset = entry.nextEntry; } if (entryOffset > 0) { f.seekp(entryOffset, std::fstream::beg); entry.nextEntry = fileSize; f.write((char*)&entry, sizeof(entry)); } else { firstEntryOffset[entryNum] = fileSize; f.seekp(tableEntriesOffset, std::fstream::beg); f.write((char*)&firstEntryOffset[0], sizeof(int)*numberOfEntries); } f.seekp(fileSize, std::fstream::beg); entry.nextEntry = 0; entry.dataSize = buf.size(); entry.optionsLength = options.length(); f.write((char*)&entry, sizeof(entry)); f.write(options.c_str(), entry.optionsLength); f.write(&buf[0], entry.dataSize); return true; }
static void* imdecode_( const Mat& buf, int flags, int hdrtype, Mat* mat=0 ) { CV_Assert(buf.data && buf.isContinuous()); IplImage* image = 0; CvMat *matrix = 0; Mat temp, *data = &temp; String filename; ImageDecoder decoder = findDecoder(buf); if( !decoder ) return 0; if( !decoder->setSource(buf) ) { filename = tempfile(); FILE* f = fopen( filename.c_str(), "wb" ); if( !f ) return 0; size_t bufSize = buf.cols*buf.rows*buf.elemSize(); fwrite( &buf.data[0], 1, bufSize, f ); fclose(f); decoder->setSource(filename); } if( !decoder->readHeader() ) { if( !filename.empty() ) remove(filename.c_str()); return 0; } CvSize size; size.width = decoder->width(); size.height = decoder->height(); int type = decoder->type(); if( flags != -1 ) { if( (flags & CV_LOAD_IMAGE_ANYDEPTH) == 0 ) type = CV_MAKETYPE(CV_8U, CV_MAT_CN(type)); if( (flags & CV_LOAD_IMAGE_COLOR) != 0 || ((flags & CV_LOAD_IMAGE_ANYCOLOR) != 0 && CV_MAT_CN(type) > 1) ) type = CV_MAKETYPE(CV_MAT_DEPTH(type), 3); else type = CV_MAKETYPE(CV_MAT_DEPTH(type), 1); } if( hdrtype == LOAD_CVMAT || hdrtype == LOAD_MAT ) { if( hdrtype == LOAD_CVMAT ) { matrix = cvCreateMat( size.height, size.width, type ); temp = cvarrToMat(matrix); } else { mat->create( size.height, size.width, type ); data = mat; } } else { image = cvCreateImage( size, cvIplDepth(type), CV_MAT_CN(type) ); temp = cvarrToMat(image); } bool code = decoder->readData( *data ); if( !filename.empty() ) remove(filename.c_str()); if( !code ) { cvReleaseImage( &image ); cvReleaseMat( &matrix ); if( mat ) mat->release(); return 0; } return hdrtype == LOAD_CVMAT ? (void*)matrix : hdrtype == LOAD_IMAGE ? (void*)image : (void*)mat; }
cv::gpu::VideoReader_GPU::FormatInfo cv::gpu::VideoReader_GPU::format() const { CV_Assert( isOpened() ); return impl_->format(); }
/*! * \brief CvVideoWriter_GStreamer::open * \param filename filename to output to * \param fourcc desired codec fourcc * \param fps desired framerate * \param frameSize the size of the expected frames * \param is_color color or grayscale * \return success * * We support 2 modes of operation. Either the user enters a filename and a fourcc * code, or enters a manual pipeline description like in CvVideoCapture_Gstreamer. * In the latter case, we just push frames on the appsink with appropriate caps. * In the former case, we try to deduce the correct container from the filename, * and the correct encoder from the fourcc profile. * * If the file extension did was not recognize, an avi container is used * */ bool CvVideoWriter_GStreamer::open( const char * filename, int fourcc, double fps, CvSize frameSize, bool is_color ) { CV_FUNCNAME("CvVideoWriter_GStreamer::open"); // check arguments assert (filename); assert (fps > 0); assert (frameSize.width > 0 && frameSize.height > 0); // init gstreamer gst_initializer::init(); // init vars bool manualpipeline = true; int bufsize = 0; GError *err = NULL; const char* mime = NULL; GstStateChangeReturn stateret; GstCaps* caps = NULL; GstCaps* videocaps = NULL; #if FULL_GST_VERSION >= VERSION_NUM(0,10,32) GstCaps* containercaps = NULL; GstEncodingContainerProfile* containerprofile = NULL; GstEncodingVideoProfile* videoprofile = NULL; #endif GstIterator *it = NULL; // we first try to construct a pipeline from the given string. // if that fails, we assume it is an ordinary filename __BEGIN__; encodebin = gst_parse_launch(filename, &err); if(!encodebin) { manualpipeline = false; } if(manualpipeline) { #if GST_VERSION_MAJOR == 0 it = gst_bin_iterate_sources(GST_BIN(encodebin)); if(gst_iterator_next(it, (gpointer *)&source) != GST_ITERATOR_OK) { CV_ERROR(CV_StsError, "GStreamer: cannot find appsink in manual pipeline\n"); return false; } #else it = gst_bin_iterate_sources (GST_BIN(encodebin)); gboolean done = FALSE; GstElement *element = NULL; gchar* name = NULL; GValue value = G_VALUE_INIT; while (!done) { switch (gst_iterator_next (it, &value)) { case GST_ITERATOR_OK: element = GST_ELEMENT (g_value_get_object (&value)); name = gst_element_get_name(element); if (name){ if(strstr(name, "opencvsrc") != NULL || strstr(name, "appsrc") != NULL) { source = GST_ELEMENT ( gst_object_ref (element) ); done = TRUE; } g_free(name); } g_value_unset (&value); break; case GST_ITERATOR_RESYNC: gst_iterator_resync (it); break; case GST_ITERATOR_ERROR: case GST_ITERATOR_DONE: done = TRUE; break; } } gst_iterator_free (it); if (!source){ CV_ERROR(CV_StsError, "GStreamer: cannot find appsrc in manual pipeline\n"); return false; } #endif pipeline = encodebin; } else { pipeline = gst_pipeline_new (NULL); // we just got a filename and a fourcc code. // first, try to guess the container from the filename //encodebin = gst_element_factory_make("encodebin", NULL); //proxy old non existing fourcc ids. These were used in previous opencv versions, //but do not even exist in gstreamer any more if (fourcc == CV_FOURCC('M','P','1','V')) fourcc = CV_FOURCC('M', 'P', 'G' ,'1'); if (fourcc == CV_FOURCC('M','P','2','V')) fourcc = CV_FOURCC('M', 'P', 'G' ,'2'); if (fourcc == CV_FOURCC('D','R','A','C')) fourcc = CV_FOURCC('d', 'r', 'a' ,'c'); //create encoder caps from fourcc videocaps = gst_riff_create_video_caps(fourcc, NULL, NULL, NULL, NULL, NULL); if (!videocaps){ CV_ERROR( CV_StsUnsupportedFormat, "Gstreamer Opencv backend does not support this codec."); } //create container caps from file extension mime = filenameToMimetype(filename); if (!mime) { CV_ERROR( CV_StsUnsupportedFormat, "Gstreamer Opencv backend does not support this file type."); } #if FULL_GST_VERSION >= VERSION_NUM(0,10,32) containercaps = gst_caps_from_string(mime); //create encodebin profile containerprofile = gst_encoding_container_profile_new("container", "container", containercaps, NULL); videoprofile = gst_encoding_video_profile_new(videocaps, NULL, NULL, 1); gst_encoding_container_profile_add_profile(containerprofile, (GstEncodingProfile *) videoprofile); #endif //create pipeline elements encodebin = gst_element_factory_make("encodebin", NULL); #if FULL_GST_VERSION >= VERSION_NUM(0,10,32) g_object_set(G_OBJECT(encodebin), "profile", containerprofile, NULL); #endif source = gst_element_factory_make("appsrc", NULL); file = gst_element_factory_make("filesink", NULL); g_object_set(G_OBJECT(file), "location", filename, NULL); } if (is_color) { input_pix_fmt = GST_VIDEO_FORMAT_BGR; bufsize = frameSize.width * frameSize.height * 3; #if GST_VERSION_MAJOR == 0 caps = gst_video_format_new_caps(GST_VIDEO_FORMAT_BGR, frameSize.width, frameSize.height, int(fps), 1, 1, 1); #else caps = gst_caps_new_simple("video/x-raw", "format", G_TYPE_STRING, "BGR", "width", G_TYPE_INT, frameSize.width, "height", G_TYPE_INT, frameSize.height, "framerate", GST_TYPE_FRACTION, int(fps), 1, NULL); caps = gst_caps_fixate(caps); #endif } else { #if FULL_GST_VERSION >= VERSION_NUM(0,10,29) input_pix_fmt = GST_VIDEO_FORMAT_GRAY8; bufsize = frameSize.width * frameSize.height; #if GST_VERSION_MAJOR == 0 caps = gst_video_format_new_caps(GST_VIDEO_FORMAT_GRAY8, frameSize.width, frameSize.height, int(fps), 1, 1, 1); #else caps = gst_caps_new_simple("video/x-raw", "format", G_TYPE_STRING, "GRAY8", "width", G_TYPE_INT, frameSize.width, "height", G_TYPE_INT, frameSize.height, "framerate", GST_TYPE_FRACTION, int(fps), 1, NULL); caps = gst_caps_fixate(caps); #endif #else CV_Assert(!"Gstreamer 0.10.29 or newer is required for grayscale input"); #endif } gst_app_src_set_caps(GST_APP_SRC(source), caps); gst_app_src_set_stream_type(GST_APP_SRC(source), GST_APP_STREAM_TYPE_STREAM); gst_app_src_set_size (GST_APP_SRC(source), -1); g_object_set(G_OBJECT(source), "format", GST_FORMAT_TIME, NULL); g_object_set(G_OBJECT(source), "block", 1, NULL); g_object_set(G_OBJECT(source), "is-live", 0, NULL); g_object_set(G_OBJECT(source), "emit-signals", 1, NULL); if(!manualpipeline) { g_object_set(G_OBJECT(file), "buffer-size", bufsize, NULL); gst_bin_add_many(GST_BIN(pipeline), source, encodebin, file, NULL); if(!gst_element_link_many(source, encodebin, file, NULL)) { CV_ERROR(CV_StsError, "GStreamer: cannot link elements\n"); } } stateret = gst_element_set_state(GST_ELEMENT(pipeline), GST_STATE_PLAYING); if(stateret == GST_STATE_CHANGE_FAILURE) { CV_ERROR(CV_StsError, "GStreamer: cannot put pipeline to play\n"); } handleMessage(pipeline); framerate = fps; num_frames = 0; __END__; return true; }
void read(const FileNode& fn) { FileNode n = fn["name"]; CV_Assert(n.isString() && String(n) == name); gamma = fn["gamma"]; }
void convexityDefects( InputArray _points, InputArray _hull, OutputArray _defects ) { CV_INSTRUMENT_REGION() Mat points = _points.getMat(); int i, j = 0, npoints = points.checkVector(2, CV_32S); CV_Assert( npoints >= 0 ); if( npoints <= 3 ) { _defects.release(); return; } Mat hull = _hull.getMat(); int hpoints = hull.checkVector(1, CV_32S); CV_Assert( hpoints > 2 ); const Point* ptr = points.ptr<Point>(); const int* hptr = hull.ptr<int>(); std::vector<Vec4i> defects; // 1. recognize co-orientation of the contour and its hull bool rev_orientation = ((hptr[1] > hptr[0]) + (hptr[2] > hptr[1]) + (hptr[0] > hptr[2])) != 2; // 2. cycle through points and hull, compute defects int hcurr = hptr[rev_orientation ? 0 : hpoints-1]; CV_Assert( 0 <= hcurr && hcurr < npoints ); for( i = 0; i < hpoints; i++ ) { int hnext = hptr[rev_orientation ? hpoints - i - 1 : i]; CV_Assert( 0 <= hnext && hnext < npoints ); Point pt0 = ptr[hcurr], pt1 = ptr[hnext]; double dx0 = pt1.x - pt0.x; double dy0 = pt1.y - pt0.y; double scale = dx0 == 0 && dy0 == 0 ? 0. : 1./std::sqrt(dx0*dx0 + dy0*dy0); int defect_deepest_point = -1; double defect_depth = 0; bool is_defect = false; j=hcurr; for(;;) { // go through points to achieve next hull point j++; j &= j >= npoints ? 0 : -1; if( j == hnext ) break; // compute distance from current point to hull edge double dx = ptr[j].x - pt0.x; double dy = ptr[j].y - pt0.y; double dist = fabs(-dy0*dx + dx0*dy) * scale; if( dist > defect_depth ) { defect_depth = dist; defect_deepest_point = j; is_defect = true; } } if( is_defect ) { int idepth = cvRound(defect_depth*256); defects.push_back(Vec4i(hcurr, hnext, defect_deepest_point, idepth)); } hcurr = hnext; } Mat(defects).copyTo(_defects); }
int main(int, char**) { try { std::cout << "Parsing dataset '" << g_pDatasetInfo->m_sDatasetName << "'..." << std::endl; std::vector<std::shared_ptr<DatasetUtils::WorkGroup>> vpDatasetGroups = g_pDatasetInfo->ParseDataset(); size_t nFramesTotal = 0; // @@@ check out priority_queue? std::multimap<double,std::shared_ptr<DatasetUtils::Segm::Video::Sequence>> mSeqLoads; for(auto ppGroupIter=vpDatasetGroups.begin(); ppGroupIter!=vpDatasetGroups.end(); ++ppGroupIter) { for(auto ppBatchIter=(*ppGroupIter)->m_vpBatches.begin(); ppBatchIter!=(*ppGroupIter)->m_vpBatches.end(); ++ppBatchIter) { auto pSeq = std::dynamic_pointer_cast<DatasetUtils::Segm::Video::Sequence>(*ppBatchIter); CV_Assert(pSeq!=nullptr); nFramesTotal += pSeq->GetTotalImageCount(); mSeqLoads.insert(std::make_pair(pSeq->GetExpectedLoad(),pSeq)); } } const size_t nSeqTotal = mSeqLoads.size(); if(nSeqTotal==0 || nFramesTotal==0) throw std::runtime_error(cv::format("Could not find any sequences/frames to process for dataset '%s'",g_pDatasetInfo->m_sDatasetName.c_str())); std::cout << "Parsing complete. [" << vpDatasetGroups.size() << " group(s), " << nSeqTotal << " sequence(s)]\n" << std::endl; const time_t nStartupTime = time(nullptr); const std::string sStartupTimeStr(asctime(localtime(&nStartupTime))); std::cout << "[" << sStartupTimeStr.substr(0,sStartupTimeStr.size()-1) << "]" << std::endl; std::cout << "Executing background subtraction with " << ((g_nMaxThreads>nSeqTotal)?nSeqTotal:g_nMaxThreads) << " thread(s)..." << std::endl; size_t nSeqProcessed = 0; for(auto pSeqIter = mSeqLoads.rbegin(); pSeqIter!=mSeqLoads.rend(); ++pSeqIter) { while(g_nActiveThreads>=g_nMaxThreads) std::this_thread::sleep_for(std::chrono::milliseconds(1000)); std::cout << "\tProcessing [" << ++nSeqProcessed << "/" << nSeqTotal << "] (" << pSeqIter->second->m_sRelativePath << ", L=" << std::scientific << std::setprecision(2) << pSeqIter->first << ")" << std::endl; #if DATASET_PRECACHING pSeqIter->second->StartPrecaching(EVALUATE_OUTPUT); #endif //DATASET_PRECACHING #if (HAVE_GLSL && USE_GLSL_IMPL) AnalyzeSequence_GLSL(pSeqIter->second); #elif (HAVE_CUDA && USE_CUDA_IMPL) static_assert(false,"missing impl"); #elif (HAVE_OPENCL && USE_OPENCL_IMPL) static_assert(false,"missing impl"); #elif !USE_GPU_IMPL ++g_nActiveThreads; std::thread(AnalyzeSequence,(int)nSeqProcessed,pSeqIter->second).detach(); #endif //!USE_GPU_IMPL } while(g_nActiveThreads>0) std::this_thread::sleep_for(std::chrono::milliseconds(1000)); size_t nTotFramesProcessed = 0; for(auto pSeqIter = mSeqLoads.rbegin(); pSeqIter!=mSeqLoads.rend(); ++pSeqIter) nTotFramesProcessed += pSeqIter->second->m_nImagesProcessed.get_future().get(); const time_t nShutdownTime = time(nullptr); const std::string sShutdownTimeStr(asctime(localtime(&nShutdownTime))); std::cout << "[" << sShutdownTimeStr.substr(0,sShutdownTimeStr.size()-1) << "]\n" << std::endl; if(EVALUATE_OUTPUT && nTotFramesProcessed==nFramesTotal) { std::cout << "Writing evaluation results..." << std::endl; g_pDatasetInfo->WriteEvalResults(vpDatasetGroups); } else if(EVALUATE_OUTPUT && nTotFramesProcessed<nFramesTotal) std::cout << "Skipping eval results output, as some sequences were skipped." << std::endl; } catch(const cv::Exception& e) { std::cout << "\n!!!!!!!!!!!!!!\nTop level caught cv::Exception:\n" << e.what() << "\n!!!!!!!!!!!!!!\n" << std::endl; return 1; } catch(const std::exception& e) { std::cout << "\n!!!!!!!!!!!!!!\nTop level caught std::exception:\n" << e.what() << "\n!!!!!!!!!!!!!!\n" << std::endl; return 1; } catch(...) { std::cout << "\n!!!!!!!!!!!!!!\nTop level caught unhandled exception\n!!!!!!!!!!!!!!\n" << std::endl; return 1; } std::cout << "\nAll done." << std::endl; return 0; }
void AnalyzeSequence_GLSL(std::shared_ptr<DatasetUtils::Segm::Video::Sequence> pCurrSequence) { srand(0); // for now, assures that two consecutive runs on the same data return the same results //srand((unsigned int)time(NULL)); size_t nCurrFrameIdx = 0; size_t nNextFrameIdx = nCurrFrameIdx+1; bool bGPUContextInitialized = false; try { glfwSetErrorCallback(GLFWErrorCallback); CV_Assert(pCurrSequence.get() && pCurrSequence->GetTotalImageCount()>1); if(pCurrSequence->m_pEvaluator==nullptr && EVALUATE_OUTPUT) throw std::runtime_error(cv::format("Missing evaluation impl for video segmentation dataset '%s'",g_pDatasetInfo->m_sDatasetName.c_str())); const std::string sCurrSeqName = pCurrSequence->m_sName.size()>12?pCurrSequence->m_sName.substr(0,12):pCurrSequence->m_sName; const size_t nFrameCount = pCurrSequence->GetTotalImageCount(); const cv::Mat oROI = LIMIT_MODEL_TO_SEQUENCE_ROI?pCurrSequence->GetROI():cv::Mat(); cv::Mat oCurrInputFrame = pCurrSequence->GetInputFromIndex(nCurrFrameIdx).clone(); CV_Assert(!oCurrInputFrame.empty()); CV_Assert(oCurrInputFrame.isContinuous()); #if NEED_GT_MASK cv::Mat oCurrGTMask = pCurrSequence->GetGTFromIndex(nCurrFrameIdx).clone(); CV_Assert(!oCurrGTMask.empty() && oCurrGTMask.isContinuous()); #endif //NEED_GT_MASK #if DISPLAY_OUTPUT cv::Mat oLastInputFrame = oCurrInputFrame.clone(); #endif //DISPLAY_OUTPUT cv::Mat oNextInputFrame = pCurrSequence->GetInputFromIndex(nNextFrameIdx); #if NEED_GT_MASK #if NEED_LAST_GT_MASK cv::Mat oLastGTMask = oCurrGTMask.clone(); #endif // NEED_LAST_GT_MASK cv::Mat oNextGTMask = pCurrSequence->GetGTFromIndex(nNextFrameIdx); #endif //NEED_GT_MASK #if NEED_FG_MASK cv::Mat oLastFGMask(oCurrInputFrame.size(),CV_8UC1,cv::Scalar_<uchar>(0)); #endif //NEED_FG_MASK #if DISPLAY_OUTPUT cv::Mat oLastBGImg; #endif //DISPLAY_OUTPUT glAssert(oCurrInputFrame.channels()==1 || oCurrInputFrame.channels()==4); cv::Size oWindowSize = oCurrInputFrame.size(); // note: never construct GL classes before context initialization if(glfwInit()==GL_FALSE) glError("Failed to init GLFW"); bGPUContextInitialized = true; glfwWindowHint(GLFW_OPENGL_PROFILE,GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR,TARGET_GL_VER_MAJOR); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR,TARGET_GL_VER_MINOR); glfwWindowHint(GLFW_RESIZABLE,GL_FALSE); #if !DISPLAY_OUTPUT glfwWindowHint(GLFW_VISIBLE,GL_FALSE); #endif //!DISPLAY_OUTPUT std::unique_ptr<GLFWwindow,void(*)(GLFWwindow*)> pWindow(glfwCreateWindow(oWindowSize.width,oWindowSize.height,(pCurrSequence->m_sRelativePath+" [GPU]").c_str(),nullptr,nullptr),glfwDestroyWindow); if(!pWindow) glError("Failed to create window via GLFW"); glfwMakeContextCurrent(pWindow.get()); glewInitErrorCheck; #if USE_LOBSTER std::shared_ptr<BackgroundSubtractorLOBSTER_GLSL> pAlgo(new BackgroundSubtractorLOBSTER_GLSL()); const double dDefaultLearningRate = BGSLOBSTER_DEFAULT_LEARNING_RATE; pAlgo->initialize(oCurrInputFrame,oROI); #elif USE_SUBSENSE #error "Missing glsl impl." // ... @@@@@ std::shared_ptr<BackgroundSubtractorSuBSENSE_GLSL> pAlgo(new BackgroundSubtractorSuBSENSE_GLSL()); const double dDefaultLearningRate = 0; pAlgo->initialize(oCurrInputFrame,oROI); #elif USE_PAWCS #error "Missing glsl impl." // ... @@@@@ std::shared_ptr<BackgroundSubtractorPAWCS_GLSL> pAlgo(new BackgroundSubtractorPAWCS_GLSL()); const double dDefaultLearningRate = 0; pAlgo->initialize(oCurrInputFrame,oROI); #else //USE_VIBE || USE_PBAS #error "Missing glsl impl." // ... @@@@@ const size_t m_nInputChannels = (size_t)oCurrInputFrame.channels(); #if USE_VIBE std::shared_ptr<cv::BackgroundSubtractorViBe_GLSL> pAlgo; if(m_nInputChannels==3) pAlgo = std::shared_ptr<cv::BackgroundSubtractorViBe_GLSL>(new BackgroundSubtractorViBe_GLSL_3ch()); else pAlgo = std::shared_ptr<cv::BackgroundSubtractorViBe_GLSL>(new BackgroundSubtractorViBe_GLSL_1ch()); const double dDefaultLearningRate = BGSVIBE_DEFAULT_LEARNING_RATE; #else //USE_PBAS std::shared_ptr<cv::BackgroundSubtractorPBAS_GLSL> pAlgo; if(m_nInputChannels==3) pAlgo = std::shared_ptr<cv::BackgroundSubtractorPBAS_GLSL>(new BackgroundSubtractorPBAS_GLSL_3ch()); else pAlgo = std::shared_ptr<cv::BackgroundSubtractorPBAS_GLSL>(new BackgroundSubtractorPBAS_GLSL_1ch()); const double dDefaultLearningRate = BGSPBAS_DEFAULT_LEARNING_RATE_OVERRIDE; #endif //USE_PBAS pAlgo->initialize(oCurrInputFrame); #endif //USE_VIBE || USE_PBAS #if DISPLAY_OUTPUT bool bContinuousUpdates = false; std::string sDisplayName = pCurrSequence->m_sRelativePath; cv::namedWindow(sDisplayName); #endif //DISPLAY_OUTPUT #if (WRITE_IMG_OUTPUT || WRITE_AVI_OUTPUT) #if WRITE_AVI_OUTPUT cv::VideoWriter oSegmWriter(pCurrSequence->m_sResultsPath+"../"+pCurrSequence->m_sName+"_segm.avi",CV_FOURCC('F','F','V','1'),30,pCurrSequence->GetImageSize(),false); #endif //WRITE_AVI_OUTPUT #endif //(WRITE_IMG_OUTPUT || WRITE_AVI_OUTPUT) std::shared_ptr<GLImageProcAlgo> pGLSLAlgo = std::dynamic_pointer_cast<GLImageProcAlgo>(pAlgo); if(pGLSLAlgo==nullptr) glError("Segmentation algorithm has no GLImageProcAlgo interface"); pGLSLAlgo->setOutputFetching(NEED_FG_MASK); if(!pGLSLAlgo->getIsUsingDisplay() && DISPLAY_OUTPUT) // @@@@ determine in advance to hint window to hide? or just always hide, and show when needed? glfwHideWindow(pWindow.get()); #if USE_GLSL_EVALUATION std::shared_ptr<DatasetUtils::EvaluatorBase::GLEvaluatorBase> pGLSLAlgoEvaluator; if(pCurrSequence->m_pEvaluator!=nullptr) pGLSLAlgoEvaluator = std::dynamic_pointer_cast<DatasetUtils::EvaluatorBase::GLEvaluatorBase>(pCurrSequence->m_pEvaluator->CreateGLEvaluator(pGLSLAlgo,nFrameCount)); if(pGLSLAlgoEvaluator==nullptr) glError("Segmentation evaluation algorithm has no GLSegmEvaluator interface"); pGLSLAlgoEvaluator->initialize(oCurrGTMask,oROI.empty()?cv::Mat(oCurrInputFrame.size(),CV_8UC1,cv::Scalar_<uchar>(255)):oROI); oWindowSize.width *= pGLSLAlgoEvaluator->m_nSxSDisplayCount; #else //!USE_GLSL_EVALUATION oWindowSize.width *= pGLSLAlgo->m_nSxSDisplayCount; #endif //!USE_GLSL_EVALUATION glfwSetWindowSize(pWindow.get(),oWindowSize.width,oWindowSize.height); glViewport(0,0,oWindowSize.width,oWindowSize.height); TIMER_TIC(MainLoop); while(nNextFrameIdx<=nFrameCount) { if(!((nCurrFrameIdx+1)%100)) std::cout << "\t\t" << std::setfill(' ') << std::setw(12) << sCurrSeqName << " @ F:" << std::setfill('0') << std::setw(PlatformUtils::decimal_integer_digit_count((int)nFrameCount)) << nCurrFrameIdx+1 << "/" << nFrameCount << " [GPU]" << std::endl; const double dCurrLearningRate = (BOOTSTRAP_100_FIRST_FRAMES&&nCurrFrameIdx<=100)?1:dDefaultLearningRate; TIMER_INTERNAL_TIC(OverallLoop); TIMER_INTERNAL_TIC(PipelineUpdate); pAlgo->apply_async(oNextInputFrame,dCurrLearningRate); TIMER_INTERNAL_TOC(PipelineUpdate); #if USE_GLSL_EVALUATION pGLSLAlgoEvaluator->apply_async(oNextGTMask); #endif //USE_GLSL_EVALUATION TIMER_INTERNAL_TIC(VideoQuery); #if DISPLAY_OUTPUT oCurrInputFrame.copyTo(oLastInputFrame); oNextInputFrame.copyTo(oCurrInputFrame); #endif //DISPLAY_OUTPUT if(++nNextFrameIdx<nFrameCount) oNextInputFrame = pCurrSequence->GetInputFromIndex(nNextFrameIdx); #if DEBUG_OUTPUT cv::imshow(sMouseDebugDisplayName,oNextInputFrame); #endif //DEBUG_OUTPUT #if NEED_GT_MASK #if NEED_LAST_GT_MASK oCurrGTMask.copyTo(oLastGTMask); oNextGTMask.copyTo(oCurrGTMask); #endif //NEED_LAST_GT_MASK if(nNextFrameIdx<nFrameCount) oNextGTMask = pCurrSequence->GetGTFromIndex(nNextFrameIdx); #endif //NEED_GT_MASK TIMER_INTERNAL_TOC(VideoQuery); glErrorCheck; if(glfwWindowShouldClose(pWindow.get())) break; glfwPollEvents(); #if DISPLAY_OUTPUT if(glfwGetKey(pWindow.get(),GLFW_KEY_ESCAPE) || glfwGetKey(pWindow.get(),GLFW_KEY_Q)) break; glfwSwapBuffers(pWindow.get()); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); #endif //DISPLAY_OUTPUT #if NEED_FG_MASK pAlgo->getLatestForegroundMask(oLastFGMask); if(!oROI.empty()) cv::bitwise_or(oLastFGMask,UCHAR_MAX/2,oLastFGMask,oROI==0); #endif //NEED_FG_MASK #if DISPLAY_OUTPUT pAlgo->getBackgroundImage(oLastBGImg); if(!oROI.empty()) cv::bitwise_or(oLastBGImg,UCHAR_MAX/2,oLastBGImg,oROI==0); cv::Mat oDisplayFrame = DatasetUtils::GetDisplayImage(oLastInputFrame,oLastBGImg,pCurrSequence->m_pEvaluator?pCurrSequence->m_pEvaluator->GetColoredSegmMaskFromResult(oLastFGMask,oLastGTMask,oROI):oLastFGMask,nCurrFrameIdx); cv::Mat oDisplayFrameResized; if(oDisplayImage.cols>1920 || oDisplayImage.rows>1080) cv::resize(oDisplayFrame,oDisplayFrameResized,cv::Size(oDisplayFrame.cols/2,oDisplayFrame.rows/2)); else oDisplayFrameResized = oDisplayFrame; cv::imshow(sDisplayName,oDisplayFrameResized); int nKeyPressed; if(bContinuousUpdates) nKeyPressed = cv::waitKey(1); else nKeyPressed = cv::waitKey(0); if(nKeyPressed!=-1) nKeyPressed %= (UCHAR_MAX+1); // fixes return val bug in some opencv versions if(nKeyPressed==' ') bContinuousUpdates = !bContinuousUpdates; else if(nKeyPressed==(int)'q') break; #endif //DISPLAY_OUTPUT #if WRITE_AVI_OUTPUT oSegmWriter.write(oLastFGMask); #endif //WRITE_AVI_OUTPUT #if WRITE_IMG_OUTPUT pCurrSequence->WriteResult(nCurrFrameIdx,oLastFGMask); #endif //WRITE_IMG_OUTPUT #if (EVALUATE_OUTPUT && (!USE_GLSL_EVALUATION || VALIDATE_GPU_EVALUATION)) if(pCurrSequence->m_pEvaluator) pCurrSequence->m_pEvaluator->AccumulateMetricsFromResult(oCurrFGMask,oCurrGTMask,oROI); #endif //(EVALUATE_OUTPUT && (!USE_GLSL_EVALUATION || VALIDATE_GPU_EVALUATION)) TIMER_INTERNAL_TOC(OverallLoop); #if DISPLAY_TIMERS std::cout << "VideoQuery=" << TIMER_INTERNAL_ELAPSED_MS(VideoQuery) << "ms, " << "PipelineUpdate=" << TIMER_INTERNAL_ELAPSED_MS(PipelineUpdate) << "ms, " << "OverallLoop=" << TIMER_INTERNAL_ELAPSED_MS(OverallLoop) << "ms" << std::endl; #endif //ENABLE_INTERNAL_TIMERS ++nCurrFrameIdx; } TIMER_TOC(MainLoop); const double dTimeElapsed = TIMER_ELAPSED_MS(MainLoop)/1000; const double dAvgFPS = (double)nCurrFrameIdx/dTimeElapsed; std::cout << "\t\t" << std::setfill(' ') << std::setw(12) << sCurrSeqName << " @ end, " << int(dTimeElapsed) << " sec in-thread (" << (int)floor(dAvgFPS+0.5) << " FPS)" << std::endl; #if EVALUATE_OUTPUT if(pCurrSequence->m_pEvaluator) { #if USE_GLSL_EVALUATION #if VALIDATE_GPU_EVALUATION printf("cpu eval:\n\tnTP=%" PRIu64 ", nTN=%" PRIu64 ", nFP=%" PRIu64 ", nFN=%" PRIu64 ", nSE=%" PRIu64 ", tot=%" PRIu64 "\n",pCurrSequence->m_pEvaluator->m_oBasicMetrics.nTP,pCurrSequence->m_pEvaluator->m_oBasicMetrics.nTN,pCurrSequence->m_pEvaluator->m_oBasicMetrics.nFP,pCurrSequence->m_pEvaluator->m_oBasicMetrics.nFN,pCurrSequence->m_pEvaluator->m_oBasicMetrics.nSE,pCurrSequence->m_pEvaluator->m_oBasicMetrics.nTP+pCurrSequence->m_pEvaluator->m_oBasicMetrics.nTN+pCurrSequence->m_pEvaluator->m_oBasicMetrics.nFP+pCurrSequence->m_pEvaluator->m_oBasicMetrics.nFN); #endif //VALIDATE_USE_GLSL_EVALUATION pCurrSequence->m_pEvaluator->FetchGLEvaluationResults(pGLSLAlgoEvaluator); #if VALIDATE_GPU_EVALUATION printf("gpu eval:\n\tnTP=%" PRIu64 ", nTN=%" PRIu64 ", nFP=%" PRIu64 ", nFN=%" PRIu64 ", nSE=%" PRIu64 ", tot=%" PRIu64 "\n",pCurrSequence->m_pEvaluator->m_oBasicMetrics.nTP,pCurrSequence->m_pEvaluator->m_oBasicMetrics.nTN,pCurrSequence->m_pEvaluator->m_oBasicMetrics.nFP,pCurrSequence->m_pEvaluator->m_oBasicMetrics.nFN,pCurrSequence->m_pEvaluator->m_oBasicMetrics.nSE,pCurrSequence->m_pEvaluator->m_oBasicMetrics.nTP+pCurrSequence->m_pEvaluator->m_oBasicMetrics.nTN+pCurrSequence->m_pEvaluator->m_oBasicMetrics.nFP+pCurrSequence->m_pEvaluator->m_oBasicMetrics.nFN); #endif //VALIDATE_USE_GLSL_EVALUATION #endif //USE_GLSL_EVALUATION pCurrSequence->m_pEvaluator->dTimeElapsed_sec = dTimeElapsed; } #endif //EVALUATE_OUTPUT #if DISPLAY_OUTPUT cv::destroyWindow(sDisplayName); #endif //DISPLAY_OUTPUT } catch(const CxxUtils::Exception& e) { std::cout << "\nAnalyzeSequence caught Exception:\n" << e.what(); if(!g_sLatestGLFWErrorMessage.empty()) { std::cout << " (" << g_sLatestGLFWErrorMessage << ")" << "\n" << std::endl; g_sLatestGLFWErrorMessage = std::string(); } else std::cout << "\n" << std::endl; } catch(const cv::Exception& e) { std::cout << "\nAnalyzeSequence caught cv::Exception:\n" << e.what() << "\n" << std::endl; } catch(const std::exception& e) { std::cout << "\nAnalyzeSequence caught std::exception:\n" << e.what() << "\n" << std::endl; } catch(...) { std::cout << "\nAnalyzeSequence caught unhandled exception\n" << std::endl; } if(bGPUContextInitialized) glfwTerminate(); if(pCurrSequence.get()) { #if DATASET_PRECACHING pCurrSequence->StopPrecaching(); #endif //DATASET_PRECACHING pCurrSequence->m_nImagesProcessed.set_value(nCurrFrameIdx); } }
void cv::merge(const Mat* mv, size_t n, OutputArray _dst) { CV_Assert( mv && n > 0 ); int depth = mv[0].depth(); bool allch1 = true; int k, cn = 0; size_t i; for( i = 0; i < n; i++ ) { CV_Assert(mv[i].size == mv[0].size && mv[i].depth() == depth); allch1 = allch1 && mv[i].channels() == 1; cn += mv[i].channels(); } CV_Assert( 0 < cn && cn <= CV_CN_MAX ); _dst.create(mv[0].dims, mv[0].size, CV_MAKETYPE(depth, cn)); Mat dst = _dst.getMat(); if( n == 1 ) { mv[0].copyTo(dst); return; } if( !allch1 ) { AutoBuffer<int> pairs(cn*2); int j, ni=0; for( i = 0, j = 0; i < n; i++, j += ni ) { ni = mv[i].channels(); for( k = 0; k < ni; k++ ) { pairs[(j+k)*2] = j + k; pairs[(j+k)*2+1] = j + k; } } mixChannels( mv, n, &dst, 1, &pairs[0], cn ); return; } size_t esz = dst.elemSize(), esz1 = dst.elemSize1(); int blocksize0 = (int)((BLOCK_SIZE + esz-1)/esz); AutoBuffer<uchar> _buf((cn+1)*(sizeof(Mat*) + sizeof(uchar*)) + 16); const Mat** arrays = (const Mat**)(uchar*)_buf; uchar** ptrs = (uchar**)alignPtr(arrays + cn + 1, 16); arrays[0] = &dst; for( k = 0; k < cn; k++ ) arrays[k+1] = &mv[k]; NAryMatIterator it(arrays, ptrs, cn+1); int total = (int)it.size, blocksize = cn <= 4 ? total : std::min(total, blocksize0); MergeFunc func = mergeTab[depth]; for( i = 0; i < it.nplanes; i++, ++it ) { for( int j = 0; j < total; j += blocksize ) { int bsz = std::min(total - j, blocksize); func( (const uchar**)&ptrs[1], ptrs[0], bsz, cn ); if( j + blocksize < total ) { ptrs[0] += bsz*esz; for( int k = 0; k < cn; k++ ) ptrs[k+1] += bsz*esz1; } } } }
void cv::mixChannels( const Mat* src, size_t nsrcs, Mat* dst, size_t ndsts, const int* fromTo, size_t npairs ) { if( npairs == 0 ) return; CV_Assert( src && nsrcs > 0 && dst && ndsts > 0 && fromTo && npairs > 0 ); size_t i, j, k, esz1 = dst[0].elemSize1(); int depth = dst[0].depth(); AutoBuffer<uchar> buf((nsrcs + ndsts + 1)*(sizeof(Mat*) + sizeof(uchar*)) + npairs*(sizeof(uchar*)*2 + sizeof(int)*6)); const Mat** arrays = (const Mat**)(uchar*)buf; uchar** ptrs = (uchar**)(arrays + nsrcs + ndsts); const uchar** srcs = (const uchar**)(ptrs + nsrcs + ndsts + 1); uchar** dsts = (uchar**)(srcs + npairs); int* tab = (int*)(dsts + npairs); int *sdelta = (int*)(tab + npairs*4), *ddelta = sdelta + npairs; for( i = 0; i < nsrcs; i++ ) arrays[i] = &src[i]; for( i = 0; i < ndsts; i++ ) arrays[i + nsrcs] = &dst[i]; ptrs[nsrcs + ndsts] = 0; for( i = 0; i < npairs; i++ ) { int i0 = fromTo[i*2], i1 = fromTo[i*2+1]; if( i0 >= 0 ) { for( j = 0; j < nsrcs; i0 -= src[j].channels(), j++ ) if( i0 < src[j].channels() ) break; CV_Assert(j < nsrcs && src[j].depth() == depth); tab[i*4] = (int)j; tab[i*4+1] = (int)(i0*esz1); sdelta[i] = src[j].channels(); } else { tab[i*4] = (int)(nsrcs + ndsts); tab[i*4+1] = 0; sdelta[i] = 0; } for( j = 0; j < ndsts; i1 -= dst[j].channels(), j++ ) if( i1 < dst[j].channels() ) break; CV_Assert(i1 >= 0 && j < ndsts && dst[j].depth() == depth); tab[i*4+2] = (int)(j + nsrcs); tab[i*4+3] = (int)(i1*esz1); ddelta[i] = dst[j].channels(); } NAryMatIterator it(arrays, ptrs, (int)(nsrcs + ndsts)); int total = (int)it.size, blocksize = std::min(total, (int)((BLOCK_SIZE + esz1-1)/esz1)); MixChannelsFunc func = mixchTab[depth]; for( i = 0; i < it.nplanes; i++, ++it ) { for( k = 0; k < npairs; k++ ) { srcs[k] = ptrs[tab[k*4]] + tab[k*4+1]; dsts[k] = ptrs[tab[k*4+2]] + tab[k*4+3]; } for( int j = 0; j < total; j += blocksize ) { int bsz = std::min(total - j, blocksize); func( srcs, sdelta, dsts, ddelta, bsz, (int)npairs ); if( j + blocksize < total ) for( k = 0; k < npairs; k++ ) { srcs[k] += blocksize*sdelta[k]*esz1; dsts[k] += blocksize*ddelta[k]*esz1; } } } }
Vec2d computeProbabilities(const Mat& sample, Mat* probs, int ptype) const { // L_ik = log(weight_k) - 0.5 * log(|det(cov_k)|) - 0.5 *(x_i - mean_k)' cov_k^(-1) (x_i - mean_k)] // q = arg(max_k(L_ik)) // probs_ik = exp(L_ik - L_iq) / (1 + sum_j!=q (exp(L_ij - L_iq)) // see Alex Smola's blog http://blog.smola.org/page/2 for // details on the log-sum-exp trick int stype = sample.type(); CV_Assert(!means.empty()); CV_Assert((stype == CV_32F || stype == CV_64F) && (ptype == CV_32F || ptype == CV_64F)); CV_Assert(sample.size() == Size(means.cols, 1)); int dim = sample.cols; Mat L(1, nclusters, CV_64FC1), centeredSample(1, dim, CV_64F); int i, label = 0; for(int clusterIndex = 0; clusterIndex < nclusters; clusterIndex++) { const double* mptr = means.ptr<double>(clusterIndex); double* dptr = centeredSample.ptr<double>(); if( stype == CV_32F ) { const float* sptr = sample.ptr<float>(); for( i = 0; i < dim; i++ ) dptr[i] = sptr[i] - mptr[i]; } else { const double* sptr = sample.ptr<double>(); for( i = 0; i < dim; i++ ) dptr[i] = sptr[i] - mptr[i]; } Mat rotatedCenteredSample = covMatType != COV_MAT_GENERIC ? centeredSample : centeredSample * covsRotateMats[clusterIndex]; double Lval = 0; for(int di = 0; di < dim; di++) { double w = invCovsEigenValues[clusterIndex].at<double>(covMatType != COV_MAT_SPHERICAL ? di : 0); double val = rotatedCenteredSample.at<double>(di); Lval += w * val * val; } CV_DbgAssert(!logWeightDivDet.empty()); L.at<double>(clusterIndex) = logWeightDivDet.at<double>(clusterIndex) - 0.5 * Lval; if(L.at<double>(clusterIndex) > L.at<double>(label)) label = clusterIndex; } double maxLVal = L.at<double>(label); double expDiffSum = 0; for( i = 0; i < L.cols; i++ ) { double v = std::exp(L.at<double>(i) - maxLVal); L.at<double>(i) = v; expDiffSum += v; // sum_j(exp(L_ij - L_iq)) } if(probs) L.convertTo(*probs, ptype, 1./expDiffSum); Vec2d res; res[0] = std::log(expDiffSum) + maxLVal - 0.5 * dim * CV_LOG2PI; res[1] = label; return res; }
bool doTrain(int startStep, OutputArray logLikelihoods, OutputArray labels, OutputArray probs) { int dim = trainSamples.cols; // Precompute the empty initial train data in the cases of START_E_STEP and START_AUTO_STEP if(startStep != START_M_STEP) { if(covs.empty()) { CV_Assert(weights.empty()); clusterTrainSamples(); } } if(!covs.empty() && covsEigenValues.empty() ) { CV_Assert(invCovsEigenValues.empty()); decomposeCovs(); } if(startStep == START_M_STEP) mStep(); double trainLogLikelihood, prevTrainLogLikelihood = 0.; int maxIters = (termCrit.type & TermCriteria::MAX_ITER) ? termCrit.maxCount : DEFAULT_MAX_ITERS; double epsilon = (termCrit.type & TermCriteria::EPS) ? termCrit.epsilon : 0.; for(int iter = 0; ; iter++) { eStep(); trainLogLikelihood = sum(trainLogLikelihoods)[0]; if(iter >= maxIters - 1) break; double trainLogLikelihoodDelta = trainLogLikelihood - prevTrainLogLikelihood; if( iter != 0 && (trainLogLikelihoodDelta < -DBL_EPSILON || trainLogLikelihoodDelta < epsilon * std::fabs(trainLogLikelihood))) break; mStep(); prevTrainLogLikelihood = trainLogLikelihood; } if( trainLogLikelihood <= -DBL_MAX/10000. ) { clear(); return false; } // postprocess covs covs.resize(nclusters); for(int clusterIndex = 0; clusterIndex < nclusters; clusterIndex++) { if(covMatType == COV_MAT_SPHERICAL) { covs[clusterIndex].create(dim, dim, CV_64FC1); setIdentity(covs[clusterIndex], Scalar(covsEigenValues[clusterIndex].at<double>(0))); } else if(covMatType == COV_MAT_DIAGONAL) { covs[clusterIndex] = Mat::diag(covsEigenValues[clusterIndex]); } } if(labels.needed()) trainLabels.copyTo(labels); if(probs.needed()) trainProbs.copyTo(probs); if(logLikelihoods.needed()) trainLogLikelihoods.copyTo(logLikelihoods); trainSamples.release(); trainProbs.release(); trainLabels.release(); trainLogLikelihoods.release(); return true; }
static void checkTrainData(int startStep, const Mat& samples, int nclusters, int covMatType, const Mat* probs, const Mat* means, const std::vector<Mat>* covs, const Mat* weights) { // Check samples. CV_Assert(!samples.empty()); CV_Assert(samples.channels() == 1); int nsamples = samples.rows; int dim = samples.cols; // Check training params. CV_Assert(nclusters > 0); CV_Assert(nclusters <= nsamples); CV_Assert(startStep == START_AUTO_STEP || startStep == START_E_STEP || startStep == START_M_STEP); CV_Assert(covMatType == COV_MAT_GENERIC || covMatType == COV_MAT_DIAGONAL || covMatType == COV_MAT_SPHERICAL); CV_Assert(!probs || (!probs->empty() && probs->rows == nsamples && probs->cols == nclusters && (probs->type() == CV_32FC1 || probs->type() == CV_64FC1))); CV_Assert(!weights || (!weights->empty() && (weights->cols == 1 || weights->rows == 1) && static_cast<int>(weights->total()) == nclusters && (weights->type() == CV_32FC1 || weights->type() == CV_64FC1))); CV_Assert(!means || (!means->empty() && means->rows == nclusters && means->cols == dim && means->channels() == 1)); CV_Assert(!covs || (!covs->empty() && static_cast<int>(covs->size()) == nclusters)); if(covs) { const Size covSize(dim, dim); for(size_t i = 0; i < covs->size(); i++) { const Mat& m = (*covs)[i]; CV_Assert(!m.empty() && m.size() == covSize && (m.channels() == 1)); } } if(startStep == START_E_STEP) { CV_Assert(means); } else if(startStep == START_M_STEP) { CV_Assert(probs); } }
virtual void read(const FileNode& fn) { CV_Assert( (String)fn["name"] == name_ ); nDummies = (int)fn["dummies"]; defaultCost = (float)fn["default"]; }
void AnalyzeSequence(int nThreadIdx, std::shared_ptr<DatasetUtils::Segm::Video::Sequence> pCurrSequence) { srand(0); // for now, assures that two consecutive runs on the same data return the same results //srand((unsigned int)time(NULL)); size_t nCurrFrameIdx = 0; try { CV_Assert(pCurrSequence.get() && pCurrSequence->GetTotalImageCount()>1); if(pCurrSequence->m_pEvaluator==nullptr && EVALUATE_OUTPUT) throw std::runtime_error(cv::format("Missing evaluation impl for video segmentation dataset '%s'",g_pDatasetInfo->m_sDatasetName.c_str())); const std::string sCurrSeqName = pCurrSequence->m_sName.size()>12?pCurrSequence->m_sName.substr(0,12):pCurrSequence->m_sName; const size_t nFrameCount = pCurrSequence->GetTotalImageCount(); const cv::Mat oROI = LIMIT_MODEL_TO_SEQUENCE_ROI?pCurrSequence->GetROI():cv::Mat(); cv::Mat oCurrInputFrame = pCurrSequence->GetInputFromIndex(nCurrFrameIdx).clone(); CV_Assert(!oCurrInputFrame.empty()); CV_Assert(oCurrInputFrame.isContinuous()); #if NEED_GT_MASK cv::Mat oCurrGTMask = pCurrSequence->GetGTFromIndex(nCurrFrameIdx).clone(); CV_Assert(!oCurrGTMask.empty() && oCurrGTMask.isContinuous()); #endif //NEED_GT_MASK cv::Mat oCurrFGMask(oCurrInputFrame.size(),CV_8UC1,cv::Scalar_<uchar>(0)); #if DISPLAY_OUTPUT cv::Mat oCurrBGImg; #endif //DISPLAY_OUTPUT #if USE_LOBSTER std::shared_ptr<BackgroundSubtractorLOBSTER> pAlgo(new BackgroundSubtractorLOBSTER()); const double dDefaultLearningRate = BGSLOBSTER_DEFAULT_LEARNING_RATE; pAlgo->initialize(oCurrInputFrame,oROI); #elif USE_SUBSENSE std::shared_ptr<BackgroundSubtractorSuBSENSE> pAlgo(new BackgroundSubtractorSuBSENSE()); const double dDefaultLearningRate = 0; pAlgo->initialize(oCurrInputFrame,oROI); #elif USE_PAWCS std::shared_ptr<BackgroundSubtractorPAWCS> pAlgo(new BackgroundSubtractorPAWCS()); const double dDefaultLearningRate = 0; pAlgo->initialize(oCurrInputFrame,oROI); #else //USE_VIBE || USE_PBAS const size_t m_nInputChannels = (size_t)oCurrInputFrame.channels(); #if USE_VIBE std::shared_ptr<BackgroundSubtractorViBe> pAlgo; if(m_nInputChannels==3) pAlgo = std::shared_ptr<BackgroundSubtractorViBe>(new BackgroundSubtractorViBe_3ch()); else pAlgo = std::shared_ptr<BackgroundSubtractorViBe>(new BackgroundSubtractorViBe_1ch()); const double dDefaultLearningRate = BGSVIBE_DEFAULT_LEARNING_RATE; #else //USE_PBAS std::shared_ptr<BackgroundSubtractorPBAS> pAlgo; if(m_nInputChannels==3) pAlgo = std::shared_ptr<BackgroundSubtractorPBAS>(new BackgroundSubtractorPBAS_3ch()); else pAlgo = std::shared_ptr<BackgroundSubtractorPBAS>(new BackgroundSubtractorPBAS_1ch()); const double dDefaultLearningRate = BGSPBAS_DEFAULT_LEARNING_RATE_OVERRIDE; #endif //USE_PBAS pAlgo->initialize(oCurrInputFrame); #endif //USE_VIBE || USE_PBAS #if (DEBUG_OUTPUT && (USE_LOBSTER || USE_SUBSENSE || USE_PAWCS)) cv::FileStorage oDebugFS = cv::FileStorage(pCurrSequence->m_sResultsPath+"../"+pCurrSequence->m_sName+"_debug.yml",cv::FileStorage::WRITE); pAlgo->m_pDebugFS = &oDebugFS; pAlgo->m_sDebugName = pCurrSequence->m_sName; g_pnLatestMouseX = &pAlgo->m_nDebugCoordX; g_pnLatestMouseY = &pAlgo->m_nDebugCoordY; std::string sMouseDebugDisplayName = pCurrSequence->m_sName + " [MOUSE DEBUG]"; cv::namedWindow(sMouseDebugDisplayName,0); cv::setMouseCallback(sMouseDebugDisplayName,OnMouseEvent,nullptr); #endif //(DEBUG_OUTPUT && (USE_LOBSTER || USE_SUBSENSE || USE_PAWCS)) #if DISPLAY_OUTPUT bool bContinuousUpdates = false; std::string sDisplayName = pCurrSequence->m_sRelativePath; cv::namedWindow(sDisplayName); #endif //DISPLAY_OUTPUT #if (WRITE_IMG_OUTPUT || WRITE_AVI_OUTPUT) #if WRITE_AVI_OUTPUT cv::VideoWriter oSegmWriter(pCurrSequence->m_sResultsPath+"../"+pCurrSequence->m_sName+"_segm.avi",CV_FOURCC('F','F','V','1'),30,pCurrSequence->GetImageSize(),false); #endif //WRITE_AVI_OUTPUT #endif //(WRITE_IMG_OUTPUT || WRITE_AVI_OUTPUT) TIMER_TIC(MainLoop); while(nCurrFrameIdx<nFrameCount) { if(!((nCurrFrameIdx+1)%100)) std::cout << "\t\t" << std::setfill(' ') << std::setw(12) << sCurrSeqName << " @ F:" << std::setfill('0') << std::setw(PlatformUtils::decimal_integer_digit_count((int)nFrameCount)) << nCurrFrameIdx+1 << "/" << nFrameCount << " [T=" << nThreadIdx << "]" << std::endl; const double dCurrLearningRate = (BOOTSTRAP_100_FIRST_FRAMES&&nCurrFrameIdx<=100)?1:dDefaultLearningRate; TIMER_INTERNAL_TIC(OverallLoop); TIMER_INTERNAL_TIC(VideoQuery); oCurrInputFrame = pCurrSequence->GetInputFromIndex(nCurrFrameIdx); #if DEBUG_OUTPUT cv::imshow(sMouseDebugDisplayName,oCurrInputFrame); #endif //DEBUG_OUTPUT #if NEED_GT_MASK oCurrGTMask = pCurrSequence->GetGTFromIndex(nCurrFrameIdx); #endif //NEED_GT_MASK TIMER_INTERNAL_TOC(VideoQuery); TIMER_INTERNAL_TIC(PipelineUpdate); pAlgo->apply(oCurrInputFrame,oCurrFGMask,dCurrLearningRate); TIMER_INTERNAL_TOC(PipelineUpdate); if(!oROI.empty()) cv::bitwise_or(oCurrFGMask,UCHAR_MAX/2,oCurrFGMask,oROI==0); #if DISPLAY_OUTPUT pAlgo->getBackgroundImage(oCurrBGImg); if(!oROI.empty()) cv::bitwise_or(oCurrBGImg,UCHAR_MAX/2,oCurrBGImg,oROI==0); cv::Mat oDisplayFrame = DatasetUtils::GetDisplayImage(oCurrInputFrame,oCurrBGImg,pCurrSequence->m_pEvaluator?pCurrSequence->m_pEvaluator->GetColoredSegmMaskFromResult(oCurrFGMask,oCurrGTMask,oROI):oCurrFGMask,nCurrFrameIdx,cv::Point(*g_pnLatestMouseX,*g_pnLatestMouseY)); cv::Mat oDisplayFrameResized; if(oDisplayFrame.cols>1920 || oDisplayFrame.rows>1080) cv::resize(oDisplayFrame,oDisplayFrameResized,cv::Size(oDisplayFrame.cols/2,oDisplayFrame.rows/2)); else oDisplayFrameResized = oDisplayFrame; cv::imshow(sDisplayName,oDisplayFrameResized); int nKeyPressed; if(bContinuousUpdates) nKeyPressed = cv::waitKey(1); else nKeyPressed = cv::waitKey(0); if(nKeyPressed!=-1) nKeyPressed %= (UCHAR_MAX+1); // fixes return val bug in some opencv versions if(nKeyPressed==' ') bContinuousUpdates = !bContinuousUpdates; else if(nKeyPressed==(int)'q') break; #endif //DISPLAY_OUTPUT #if WRITE_AVI_OUTPUT oSegmWriter.write(oCurrFGMask); #endif //WRITE_AVI_OUTPUT #if WRITE_IMG_OUTPUT pCurrSequence->WriteResult(nCurrFrameIdx,oCurrFGMask); #endif //WRITE_IMG_OUTPUT #if EVALUATE_OUTPUT if(pCurrSequence->m_pEvaluator) pCurrSequence->m_pEvaluator->AccumulateMetricsFromResult(oCurrFGMask,oCurrGTMask,oROI); #endif //EVALUATE_OUTPUT TIMER_INTERNAL_TOC(OverallLoop); #if DISPLAY_TIMERS std::cout << "VideoQuery=" << TIMER_INTERNAL_ELAPSED_MS(VideoQuery) << "ms, " << "PipelineUpdate=" << TIMER_INTERNAL_ELAPSED_MS(PipelineUpdate) << "ms, " << "OverallLoop=" << TIMER_INTERNAL_ELAPSED_MS(OverallLoop) << "ms" << std::endl; #endif //ENABLE_INTERNAL_TIMERS ++nCurrFrameIdx; } TIMER_TOC(MainLoop); const double dTimeElapsed = TIMER_ELAPSED_MS(MainLoop)/1000; const double dAvgFPS = (double)nCurrFrameIdx/dTimeElapsed; std::cout << "\t\t" << std::setfill(' ') << std::setw(12) << sCurrSeqName << " @ end, " << int(dTimeElapsed) << " sec in-thread (" << (int)floor(dAvgFPS+0.5) << " FPS)" << std::endl; #if EVALUATE_OUTPUT if(pCurrSequence->m_pEvaluator) { pCurrSequence->m_pEvaluator->dTimeElapsed_sec = dTimeElapsed; //pCurrSequence->m_pEvaluator->WriteMetrics(pCurrSequence->m_sResultsPath+"../"+pCurrSequence->m_sName+".txt",*pCurrSequence); } #endif //EVALUATE_OUTPUT #if DISPLAY_OUTPUT cv::destroyWindow(sDisplayName); #endif //DISPLAY_OUTPUT #if DEBUG_OUTPUT cv::setMouseCallback(sMouseDebugDisplayName,OnMouseEvent,nullptr); cv::destroyWindow(sMouseDebugDisplayName); g_pnLatestMouseX = &g_nLatestMouseX; g_pnLatestMouseY = &g_nLatestMouseY; #endif //DEBUG_OUTPUT } catch(const cv::Exception& e) { std::cout << "\nAnalyzeSequence caught cv::Exception:\n" << e.what() << "\n" << std::endl; } catch(const std::exception& e) { std::cout << "\nAnalyzeSequence caught std::exception:\n" << e.what() << "\n" << std::endl; } catch(...) { std::cout << "\nAnalyzeSequence caught unhandled exception\n" << std::endl; } g_nActiveThreads--; if(pCurrSequence.get()) { #if DATASET_PRECACHING pCurrSequence->StopPrecaching(); #endif //DATASET_PRECACHING pCurrSequence->m_nImagesProcessed.set_value(nCurrFrameIdx); } }
static Moments contourMoments( const Mat& contour ) { Moments m; int lpt = contour.checkVector(2); int is_float = contour.depth() == CV_32F; const Point* ptsi = (const Point*)contour.data; const Point2f* ptsf = (const Point2f*)contour.data; CV_Assert( contour.depth() == CV_32S || contour.depth() == CV_32F ); if( lpt == 0 ) return m; double a00 = 0, a10 = 0, a01 = 0, a20 = 0, a11 = 0, a02 = 0, a30 = 0, a21 = 0, a12 = 0, a03 = 0; double xi, yi, xi2, yi2, xi_1, yi_1, xi_12, yi_12, dxy, xii_1, yii_1; if( !is_float ) { xi_1 = ptsi[lpt-1].x; yi_1 = ptsi[lpt-1].y; } else { xi_1 = ptsf[lpt-1].x; yi_1 = ptsf[lpt-1].y; } xi_12 = xi_1 * xi_1; yi_12 = yi_1 * yi_1; for( int i = 0; i < lpt; i++ ) { if( !is_float ) { xi = ptsi[i].x; yi = ptsi[i].y; } else { xi = ptsf[i].x; yi = ptsf[i].y; } xi2 = xi * xi; yi2 = yi * yi; dxy = xi_1 * yi - xi * yi_1; xii_1 = xi_1 + xi; yii_1 = yi_1 + yi; a00 += dxy; a10 += dxy * xii_1; a01 += dxy * yii_1; a20 += dxy * (xi_1 * xii_1 + xi2); a11 += dxy * (xi_1 * (yii_1 + yi_1) + xi * (yii_1 + yi)); a02 += dxy * (yi_1 * yii_1 + yi2); a30 += dxy * xii_1 * (xi_12 + xi2); a03 += dxy * yii_1 * (yi_12 + yi2); a21 += dxy * (xi_12 * (3 * yi_1 + yi) + 2 * xi * xi_1 * yii_1 + xi2 * (yi_1 + 3 * yi)); a12 += dxy * (yi_12 * (3 * xi_1 + xi) + 2 * yi * yi_1 * xii_1 + yi2 * (xi_1 + 3 * xi)); xi_1 = xi; yi_1 = yi; xi_12 = xi2; yi_12 = yi2; } if( fabs(a00) > FLT_EPSILON ) { double db1_2, db1_6, db1_12, db1_24, db1_20, db1_60; if( a00 > 0 ) { db1_2 = 0.5; db1_6 = 0.16666666666666666666666666666667; db1_12 = 0.083333333333333333333333333333333; db1_24 = 0.041666666666666666666666666666667; db1_20 = 0.05; db1_60 = 0.016666666666666666666666666666667; } else { db1_2 = -0.5; db1_6 = -0.16666666666666666666666666666667; db1_12 = -0.083333333333333333333333333333333; db1_24 = -0.041666666666666666666666666666667; db1_20 = -0.05; db1_60 = -0.016666666666666666666666666666667; } // spatial moments m.m00 = a00 * db1_2; m.m10 = a10 * db1_6; m.m01 = a01 * db1_6; m.m20 = a20 * db1_12; m.m11 = a11 * db1_24; m.m02 = a02 * db1_12; m.m30 = a30 * db1_20; m.m21 = a21 * db1_60; m.m12 = a12 * db1_60; m.m03 = a03 * db1_20; completeMomentState( &m ); } return m; }
void SIFT::operator()(InputArray _image, InputArray _mask, std::vector<KeyPoint>& keypoints, OutputArray _descriptors, bool useProvidedKeypoints) const { int firstOctave = -1, actualNOctaves = 0, actualNLayers = 0; Mat image = _image.getMat(), mask = _mask.getMat(); if( image.empty() || image.depth() != CV_8U ) CV_Error( Error::StsBadArg, "image is empty or has incorrect depth (!=CV_8U)" ); if( !mask.empty() && mask.type() != CV_8UC1 ) CV_Error( Error::StsBadArg, "mask has incorrect type (!=CV_8UC1)" ); if( useProvidedKeypoints ) { firstOctave = 0; int maxOctave = INT_MIN; for( size_t i = 0; i < keypoints.size(); i++ ) { int octave, layer; float scale; unpackOctave(keypoints[i], octave, layer, scale); firstOctave = std::min(firstOctave, octave); maxOctave = std::max(maxOctave, octave); actualNLayers = std::max(actualNLayers, layer-2); } firstOctave = std::min(firstOctave, 0); CV_Assert( firstOctave >= -1 && actualNLayers <= nOctaveLayers ); actualNOctaves = maxOctave - firstOctave + 1; } Mat base = createInitialImage(image, firstOctave < 0, (float)sigma); std::vector<Mat> gpyr, dogpyr; int nOctaves = actualNOctaves > 0 ? actualNOctaves : cvRound(std::log( (double)std::min( base.cols, base.rows ) ) / std::log(2.) - 2) - firstOctave; //double t, tf = getTickFrequency(); //t = (double)getTickCount(); buildGaussianPyramid(base, gpyr, nOctaves); buildDoGPyramid(gpyr, dogpyr); //t = (double)getTickCount() - t; //printf("pyramid construction time: %g\n", t*1000./tf); if( !useProvidedKeypoints ) { //t = (double)getTickCount(); findScaleSpaceExtrema(gpyr, dogpyr, keypoints); KeyPointsFilter::removeDuplicated( keypoints ); if( !mask.empty() ) KeyPointsFilter::runByPixelsMask( keypoints, mask ); if( nfeatures > 0 ) KeyPointsFilter::retainBest(keypoints, nfeatures); //t = (double)getTickCount() - t; //printf("keypoint detection time: %g\n", t*1000./tf); if( firstOctave < 0 ) for( size_t i = 0; i < keypoints.size(); i++ ) { KeyPoint& kpt = keypoints[i]; float scale = 1.f/(float)(1 << -firstOctave); kpt.octave = (kpt.octave & ~255) | ((kpt.octave + firstOctave) & 255); kpt.pt *= scale; kpt.size *= scale; } } else { // filter keypoints by mask //KeyPointsFilter::runByPixelsMask( keypoints, mask ); } if( _descriptors.needed() ) { //t = (double)getTickCount(); int dsize = descriptorSize(); _descriptors.create((int)keypoints.size(), dsize, CV_32F); Mat descriptors = _descriptors.getMat(); calcDescriptors(gpyr, keypoints, descriptors, nOctaveLayers, firstOctave); //t = (double)getTickCount() - t; //printf("descriptor extraction time: %g\n", t*1000./tf); } }
void convexHull( InputArray _points, OutputArray _hull, bool clockwise, bool returnPoints ) { CV_INSTRUMENT_REGION() Mat points = _points.getMat(); int i, total = points.checkVector(2), depth = points.depth(), nout = 0; int miny_ind = 0, maxy_ind = 0; CV_Assert(total >= 0 && (depth == CV_32F || depth == CV_32S)); if( total == 0 ) { _hull.release(); return; } returnPoints = !_hull.fixedType() ? returnPoints : _hull.type() != CV_32S; bool is_float = depth == CV_32F; AutoBuffer<Point*> _pointer(total); AutoBuffer<int> _stack(total + 2), _hullbuf(total); Point** pointer = _pointer; Point2f** pointerf = (Point2f**)pointer; Point* data0 = points.ptr<Point>(); int* stack = _stack; int* hullbuf = _hullbuf; CV_Assert(points.isContinuous()); for( i = 0; i < total; i++ ) pointer[i] = &data0[i]; // sort the point set by x-coordinate, find min and max y if( !is_float ) { std::sort(pointer, pointer + total, CHullCmpPoints<int>()); for( i = 1; i < total; i++ ) { int y = pointer[i]->y; if( pointer[miny_ind]->y > y ) miny_ind = i; if( pointer[maxy_ind]->y < y ) maxy_ind = i; } } else { std::sort(pointerf, pointerf + total, CHullCmpPoints<float>()); for( i = 1; i < total; i++ ) { float y = pointerf[i]->y; if( pointerf[miny_ind]->y > y ) miny_ind = i; if( pointerf[maxy_ind]->y < y ) maxy_ind = i; } } if( pointer[0]->x == pointer[total-1]->x && pointer[0]->y == pointer[total-1]->y ) { hullbuf[nout++] = 0; } else { // upper half int *tl_stack = stack; int tl_count = !is_float ? Sklansky_( pointer, 0, maxy_ind, tl_stack, -1, 1) : Sklansky_( pointerf, 0, maxy_ind, tl_stack, -1, 1); int *tr_stack = stack + tl_count; int tr_count = !is_float ? Sklansky_( pointer, total-1, maxy_ind, tr_stack, -1, -1) : Sklansky_( pointerf, total-1, maxy_ind, tr_stack, -1, -1); // gather upper part of convex hull to output if( !clockwise ) { std::swap( tl_stack, tr_stack ); std::swap( tl_count, tr_count ); } for( i = 0; i < tl_count-1; i++ ) hullbuf[nout++] = int(pointer[tl_stack[i]] - data0); for( i = tr_count - 1; i > 0; i-- ) hullbuf[nout++] = int(pointer[tr_stack[i]] - data0); int stop_idx = tr_count > 2 ? tr_stack[1] : tl_count > 2 ? tl_stack[tl_count - 2] : -1; // lower half int *bl_stack = stack; int bl_count = !is_float ? Sklansky_( pointer, 0, miny_ind, bl_stack, 1, -1) : Sklansky_( pointerf, 0, miny_ind, bl_stack, 1, -1); int *br_stack = stack + bl_count; int br_count = !is_float ? Sklansky_( pointer, total-1, miny_ind, br_stack, 1, 1) : Sklansky_( pointerf, total-1, miny_ind, br_stack, 1, 1); if( clockwise ) { std::swap( bl_stack, br_stack ); std::swap( bl_count, br_count ); } if( stop_idx >= 0 ) { int check_idx = bl_count > 2 ? bl_stack[1] : bl_count + br_count > 2 ? br_stack[2-bl_count] : -1; if( check_idx == stop_idx || (check_idx >= 0 && pointer[check_idx]->x == pointer[stop_idx]->x && pointer[check_idx]->y == pointer[stop_idx]->y) ) { // if all the points lie on the same line, then // the bottom part of the convex hull is the mirrored top part // (except the exteme points). bl_count = MIN( bl_count, 2 ); br_count = MIN( br_count, 2 ); } } for( i = 0; i < bl_count-1; i++ ) hullbuf[nout++] = int(pointer[bl_stack[i]] - data0); for( i = br_count-1; i > 0; i-- ) hullbuf[nout++] = int(pointer[br_stack[i]] - data0); } if( !returnPoints ) Mat(nout, 1, CV_32S, hullbuf).copyTo(_hull); else { _hull.create(nout, 1, CV_MAKETYPE(depth, 2)); Mat hull = _hull.getMat(); size_t step = !hull.isContinuous() ? hull.step[0] : sizeof(Point); for( i = 0; i < nout; i++ ) *(Point*)(hull.ptr() + i*step) = data0[hullbuf[i]]; } }
Variant SelectMax::exec() { std::vector< cv::Mat* >* matIn = NULL; // CV_32FC1 - ARRAY std::vector< cv::Mat* >* matOut = NULL; // CV_32FC1 - ARRAY { if (this->workspaceHandle.count(std::string("matIn")) == 1) { matIn = this->workspaceHandle[std::string("matIn")]; } if (this->workspaceHandle.count(std::string("matOut")) == 1) { matOut = this->workspaceHandle[std::string("matOut")]; } CV_Assert(matIn == NULL || matIn->size() == 0 || matIn->at(0)->empty() == true || matIn->at(0)->type() == CV_32FC1); CV_Assert(matOut == NULL || matOut->size() == 0 || matOut->at(0)->empty() == true || matOut->at(0)->type() == CV_32FC1); } { for (int intFor1 = 0; intFor1 < matIn->size(); intFor1 += 1) { cv::copy(cv::Mat(System::obtain()->intHeight, System::obtain()->intWidth, CV_32FC1, cv::Scalar(0.0)), *matOut->at(intFor1)); } } { System::obtain()->execProgress(this->strName, 100, 0); } { int intWidth = System::obtain()->intWidth; int intHeight = System::obtain()->intHeight; for (int intFor1 = 0; intFor1 < intHeight; intFor1 += 1) { for (int intFor2 = 0; intFor2 < intWidth; intFor2 += 1) { int intValue = 0; float fltValue = 0.0; { intValue = 0; fltValue = matIn->at(0)->at< float >(intFor1, intFor2); for (int intFor3 = 1; intFor3 < matIn->size(); intFor3 += 1) { if (matIn->at(intFor3)->at< float >(intFor1, intFor2) > fltValue) { intValue = intFor3; fltValue = matIn->at(intFor3)->at< float >(intFor1, intFor2); } } } { matOut->at(intValue)->at< float >(intFor1, intFor2) = 1.0; } } } } { System::obtain()->execProgress(this->strName, 100, 100); } return Variant(); }
void cv::gpu::VideoReader_GPU::open(const cv::Ptr<VideoSource>& source) { CV_Assert( !source.empty() ); close(); impl_.reset(new Impl(source)); }
//2D tracker int voteForSizeAndOrientation(std::vector<cv::KeyPoint>* modelKeyPoints, std::vector<cv::KeyPoint>* observedKeyPoints, std::vector< std::vector< cv::DMatch > >* matches, cv::Mat* mask, double scaleIncrement, int rotationBins) { CV_Assert(!modelKeyPoints->empty()); CV_Assert(!observedKeyPoints->empty()); CV_Assert(mask->depth() == CV_8U && mask->channels() == 1); //cv::Mat_<int> indicesMat = (cv::Mat_<int>) cv::cvarrToMat(indices); cv::Mat_<uchar> maskMat = (cv::Mat_<uchar>) *mask; std::vector<float> logScale; std::vector<float> rotations; float s, maxS, minS, r; maxS = -1.0e-10f; minS = 1.0e10f; for (int i = 0; i < maskMat.rows; i++) { if ( maskMat(i, 0)) { cv::KeyPoint observedKeyPoint = observedKeyPoints->at(i); cv::KeyPoint modelKeyPoint = modelKeyPoints->at( matches->at(i).at(0).trainIdx); s = log10( observedKeyPoint.size / modelKeyPoint.size ); logScale.push_back(s); maxS = s > maxS ? s : maxS; minS = s < minS ? s : minS; r = observedKeyPoint.angle - modelKeyPoint.angle; r = r < 0.0f? r + 360.0f : r; rotations.push_back(r); } } int scaleBinSize = cvCeil((maxS - minS) / log10(scaleIncrement)); if (scaleBinSize < 2) scaleBinSize = 2; float scaleRanges[] = {minS, (float) (minS + scaleBinSize * log10(scaleIncrement))}; cv::Mat_<float> scalesMat(logScale); cv::Mat_<float> rotationsMat(rotations); std::vector<float> flags(logScale.size()); cv::Mat flagsMat(flags); { //Perform voting for both scale and orientation int histSize[] = {scaleBinSize, rotationBins}; float rotationRanges[] = {0, 360}; int channels[] = {0, 1}; const float* ranges[] = {scaleRanges, rotationRanges}; double minVal, maxVal; const cv::Mat_<float> arrs[] = {scalesMat, rotationsMat}; cv::MatND hist; //CV_32S cv::calcHist(arrs, 2, channels, cv::Mat(), hist, 2, histSize, ranges, true); cv::minMaxLoc(hist, &minVal, &maxVal); cv::threshold(hist, hist, maxVal * 0.5, 0, cv::THRESH_TOZERO); cv::calcBackProject(arrs, 2, channels, hist, flagsMat, ranges); } int idx =0; int nonZeroCount = 0; for (int i = 0; i < maskMat.rows; i++) { if (maskMat(i, 0)) { if (flags[idx++] != 0.0f) nonZeroCount++; else maskMat(i, 0) = 0; } } return nonZeroCount; }
bool forward_ocl(InputArrayOfArrays inputs_, OutputArrayOfArrays outputs_, OutputArrayOfArrays internals_) { std::vector<UMat> inputs; std::vector<UMat> outputs; std::vector<UMat> internals; inputs_.getUMatVector(inputs); outputs_.getUMatVector(outputs); internals_.getUMatVector(internals); CV_Assert(inputs.size() == 1 && outputs.size() == 1); CV_Assert(inputs[0].total() == outputs[0].total()); const UMat& inp0 = inputs[0]; UMat& buffer = internals[0]; size_t num = inp0.size[0]; size_t channels = inp0.size[1]; size_t channelSize = inp0.total() / (num * channels); for (size_t i = 0; i < num; ++i) { MatShape s = shape(channels, channelSize); UMat src = inputs[i].reshape(1, s.size(), &s[0]); UMat dst = outputs[i].reshape(1, s.size(), &s[0]); UMat abs_mat; absdiff(src, cv::Scalar::all(0), abs_mat); pow(abs_mat, pnorm, buffer); if (acrossSpatial) { // add eps to avoid overflow float absSum = sum(buffer)[0] + epsilon; float norm = pow(absSum, 1.0f / pnorm); multiply(src, 1.0f / norm, dst); } else { Mat norm; reduce(buffer, norm, 0, REDUCE_SUM); norm += epsilon; // compute inverted norm to call multiply instead divide cv::pow(norm, -1.0f / pnorm, norm); repeat(norm, channels, 1, buffer); multiply(src, buffer, dst); } if (!blobs.empty()) { // scale the output Mat scale = blobs[0]; if (scale.total() == 1) { // _scale: 1 x 1 multiply(dst, scale.at<float>(0, 0), dst); } else { // _scale: _channels x 1 CV_Assert(scale.total() == channels); repeat(scale, 1, dst.cols, buffer); multiply(dst, buffer, dst); } } } return true; }
void setSistemConfig(config_SystemParameter *param, string fileParam){ //system param - Directory param->angleVector.clear(); param->scaleVector.clear(); //READING THE PATCH'S POSITION int length; char * buffer; ifstream is; is.open (fileParam.c_str(), ios::binary ); // get length of file: is.seekg (0, ios::end); length = is.tellg(); is.seekg (0, ios::beg); // allocate memory: buffer = new char [length]; // read data as a block: is.read (buffer,length); string content(buffer,length); stringstream ss(content); string centerS,centerS_x,centerS_y,sizeS,sizeS_w,sizeS_h,angleS, norm,rgb,videoPath, modelMemory,alpha, areaSearch,angleVector,scaleVector, time; getline(ss, time); getline(ss, centerS); getline(ss, sizeS); getline(ss, angleS); getline(ss, norm); getline(ss, videoPath); getline(ss, rgb); getline(ss, modelMemory); getline(ss, alpha); getline(ss, areaSearch); getline(ss, scaleVector); getline(ss, angleVector); //Time range param->startTimeOnFrames = isFrame(time.substr(0,time.find(','))); param->endTimeOnFrames = isFrame(time.substr(time.find(',')+1)); param->startTime = time2msec(time.substr(0,time.find(','))); param->endTime = time2msec(time.substr(time.find(',')+1)); //initialRect centerS_x = centerS.substr(0,centerS.find(',')); centerS_y = centerS.substr(centerS.find(',')+1); sizeS_w = sizeS.substr(0,sizeS.find(',')); sizeS_h = sizeS.substr(sizeS.find(',')+1); Point2f center(atof(centerS_x.c_str()),atof(centerS_y.c_str())); cv::Size size(atof(sizeS_w.c_str()),atof(sizeS_h.c_str())); param->initialRect = RotatedRect(center,size,atof(angleS.c_str())); //NormType if (!norm.compare("FACE")) param->normType = FACE;//*normType = FACE; else if(!norm.compare("PEDESTRIAN")) param->normType = PEDESTRIAN;//*normType = PEDESTRIAN; else { cout << "NOT SUCH NORM: "<<norm<<endl; CV_Assert(false); } //RGB if (!rgb.compare("1")){ param->isRGB = true; param->numFeature = 12; } else if(!rgb.compare("0")){ param->isRGB = false; param->numFeature = 10; } else { cout << "INVALID RGB VALUE: "<<rgb<<endl; CV_Assert(false); } //video path param->videoPath = videoPath; //modelMemory param->modelMemory = atof(modelMemory.c_str()); //alpha param->alpha = atof(alpha.c_str()); //areaSearch param->areaSearch = atof(areaSearch.c_str()); //scaleVector int index = 0; string aux; while (index<scaleVector.length()) { aux = scaleVector.substr(index,scaleVector.length()); aux = aux.substr(0,aux.find_first_of(',')); index += aux.length()+1; param->scaleVector.push_back(atof(aux.c_str())); } //anglesVector index = 0; while (index<angleVector.length()) { aux = angleVector.substr(index,angleVector.length()); aux = aux.substr(0,aux.find_first_of(',')); index += aux.length()+1; param->angleVector.push_back(atof(aux.c_str())); } is.close(); delete[] buffer; }
bool readConfigurationFromFile(const String& options, std::vector<char>& buf) { if (hash_ == NULL) return false; if (!f.is_open()) return false; f.seekg(0, std::fstream::end); size_t fileSize = (size_t)f.tellg(); if (fileSize == 0) { std::cerr << "Invalid file (empty): " << fileName_ << std::endl; f.close(); remove(fileName_.c_str()); return false; } f.seekg(0, std::fstream::beg); int hashLength = 0; f.read((char*)&hashLength, sizeof(int)); CV_Assert(hashLength > 0); f.seekg(sizeof(hashLength) + hashLength, std::fstream::beg); int numberOfEntries = 0; f.read((char*)&numberOfEntries, sizeof(int)); CV_Assert(numberOfEntries > 0); if (numberOfEntries != MAX_ENTRIES) { std::cerr << "Invalid file: " << fileName_ << std::endl; f.close(); remove(fileName_.c_str()); return false; } std::vector<int> firstEntryOffset(numberOfEntries); f.read((char*)&firstEntryOffset[0], sizeof(int)*numberOfEntries); int entryNum = getHash(options); int entryOffset = firstEntryOffset[entryNum]; ProgramFileConfigurationEntry entry; while (entryOffset > 0) { f.seekg(entryOffset, std::fstream::beg); assert(sizeof(entry) == sizeof(int)*3); f.read((char*)&entry, sizeof(entry)); std::vector<char> foptions(entry.optionsLength); if ((int)options.length() == entry.optionsLength) { if (entry.optionsLength > 0) f.read(&foptions[0], entry.optionsLength); if (memcmp(&foptions[0], options.c_str(), entry.optionsLength) == 0) { buf.resize(entry.dataSize); f.read(&buf[0], entry.dataSize); f.seekg(0, std::fstream::beg); return true; } } if (entry.nextEntry <= 0) break; entryOffset = entry.nextEntry; } return false; }
RotatedRect searchFace(Mat& src, GenericModel *model, cv::Size2f scaleFactor, bool draw){ GenericFeature *minFeature; Mat auxImg, auxImg2; resize(src, auxImg,cv::Size2i(scaleFactor.width*src.size().width, scaleFactor.height*src.size().height)); auxImg2 = auxImg.clone(); CvHaarClassifierCascade* cascade = (CvHaarClassifierCascade*) cvLoad (CASCADE_NAME, 0, 0, 0); CvMemStorage* storage = cvCreateMemStorage(0); assert (storage); if (! cascade) abort (); CvHaarClassifierCascade* cascadeProfile = (CvHaarClassifierCascade*) cvLoad (CASCADE_NAME_PROFILE, 0, 0, 0); CvMemStorage* storageProfile = cvCreateMemStorage(0); assert (storageProfile); if (! cascadeProfile) abort (); IplImage *gray_image = cvCreateImage(src.size(), IPL_DEPTH_8U, 1); IplImage aux = IplImage(src); cvCvtColor (&aux, gray_image, CV_BGR2GRAY); cvEqualizeHist( gray_image, gray_image ); CvSeq* faces = cvHaarDetectObjects (gray_image, cascade, storage, 1.1, 3, CV_HAAR_DO_CANNY_PRUNING, cvSize (25, 25)); CvSeq* facesProfiles = cvHaarDetectObjects (gray_image, cascadeProfile, storageProfile, 1.1, 3, CV_HAAR_DO_CANNY_PRUNING, cvSize (25, 25)); double minValue = 10000.0; RotatedRect minRect; model->updateModel(auxImg); if (draw) cvNamedWindow("ROI"); for (int i = 0; i < (faces ? faces->total : 0); i++){ CvRect* r = (CvRect*) cvGetSeqElem (faces, i); RotatedRect auxRect(Point2i(r->x+r->width/2,r->y+r->height/2),Size2i(r->width,r->height),0); auxRect = scaleRect(auxRect, cv::Size2f(scaleFactor.width, scaleFactor.height)); if (draw) drawRotatedRect(auxImg2, auxRect,CV_RGB(100,50,50) , 2); if(model->ModelType == COV_FULL_IMAGE){ //minFeature = (GenericFeature *)new CovarianceFullDescriptor(auxRect,model->tracker_param); CV_Assert(false); } else if(model->ModelType == COV_SUB_WINDOWS) minFeature = (GenericFeature *)new CovariancePatchDescriptor(auxRect,model->tracker_param); else if(model->ModelType == COV_SUB_WINDOWS_B) minFeature = (GenericFeature *)new CovariancePatchDescriptor(auxRect,model->tracker_param); minFeature->computeFeature(model); double dist = model->distance(minFeature); if (dist<minValue) { minValue = dist; minRect = auxRect; } minFeature->clear(); delete minFeature; if (draw){ cout << "dist: "<<dist<<endl; imshow( "ROI", auxImg2); cvWaitKey(); } } for (int i = 0; i < (facesProfiles ? facesProfiles->total : 0); i++){ CvRect* r = (CvRect*) cvGetSeqElem (facesProfiles, i); RotatedRect auxRect(Point2i(r->x+r->width/2,r->y+r->height/2),Size2i(r->width,r->height),0); auxRect = scaleRect(auxRect, cv::Size2f(scaleFactor.width, scaleFactor.height)); if (draw) drawRotatedRect(auxImg2, auxRect,CV_RGB(0,0,0) , 2); if(model->ModelType == COV_FULL_IMAGE){ //minFeature = (GenericFeature *)new CovarianceFullDescriptor(auxRect,model->tracker_param); CV_Assert(false); } else if(model->ModelType == COV_SUB_WINDOWS) minFeature = (GenericFeature *)new CovariancePatchDescriptor(auxRect,model->tracker_param); else if(model->ModelType == COV_SUB_WINDOWS_B) minFeature = (GenericFeature *)new CovariancePatchDescriptor(auxRect,model->tracker_param); minFeature->computeFeature(model); double dist = model->distance(minFeature); if (dist<minValue) { minValue = dist; minRect = auxRect; } minFeature->clear(); delete minFeature; if (draw){ cout << "dist: "<<dist<<endl; imshow( "ROI", auxImg2); cvWaitKey(); } } if (draw){ drawRotatedRect(auxImg2, minRect,CV_RGB(255,0,0) , 3); imshow( "ROI", auxImg2); cvWaitKey(); cvDestroyWindow("ROI"); } auxImg2.release(); auxImg.release(); cvReleaseImage(&gray_image); cvClearMemStorage(storage); cvClearMemStorage(storageProfile); return scaleRect(minRect, cv::Size2f(1/scaleFactor.width, 1/scaleFactor.height)); }
void MultiBandBlender::feed(InputArray _img, InputArray mask, Point tl) { #if ENABLE_LOG int64 t = getTickCount(); #endif UMat img = _img.getUMat(); CV_Assert(img.type() == CV_16SC3 || img.type() == CV_8UC3); CV_Assert(mask.type() == CV_8U); // Keep source image in memory with small border int gap = 3 * (1 << num_bands_); Point tl_new(std::max(dst_roi_.x, tl.x - gap), std::max(dst_roi_.y, tl.y - gap)); Point br_new(std::min(dst_roi_.br().x, tl.x + img.cols + gap), std::min(dst_roi_.br().y, tl.y + img.rows + gap)); // Ensure coordinates of top-left, bottom-right corners are divided by (1 << num_bands_). // After that scale between layers is exactly 2. // // We do it to avoid interpolation problems when keeping sub-images only. There is no such problem when // image is bordered to have size equal to the final image size, but this is too memory hungry approach. tl_new.x = dst_roi_.x + (((tl_new.x - dst_roi_.x) >> num_bands_) << num_bands_); tl_new.y = dst_roi_.y + (((tl_new.y - dst_roi_.y) >> num_bands_) << num_bands_); int width = br_new.x - tl_new.x; int height = br_new.y - tl_new.y; width += ((1 << num_bands_) - width % (1 << num_bands_)) % (1 << num_bands_); height += ((1 << num_bands_) - height % (1 << num_bands_)) % (1 << num_bands_); br_new.x = tl_new.x + width; br_new.y = tl_new.y + height; int dy = std::max(br_new.y - dst_roi_.br().y, 0); int dx = std::max(br_new.x - dst_roi_.br().x, 0); tl_new.x -= dx; br_new.x -= dx; tl_new.y -= dy; br_new.y -= dy; int top = tl.y - tl_new.y; int left = tl.x - tl_new.x; int bottom = br_new.y - tl.y - img.rows; int right = br_new.x - tl.x - img.cols; // Create the source image Laplacian pyramid UMat img_with_border; copyMakeBorder(_img, img_with_border, top, bottom, left, right, BORDER_REFLECT); LOGLN(" Add border to the source image, time: " << ((getTickCount() - t) / getTickFrequency()) << " sec"); #if ENABLE_LOG t = getTickCount(); #endif std::vector<UMat> src_pyr_laplace; if (can_use_gpu_ && img_with_border.depth() == CV_16S) createLaplacePyrGpu(img_with_border, num_bands_, src_pyr_laplace); else createLaplacePyr(img_with_border, num_bands_, src_pyr_laplace); LOGLN(" Create the source image Laplacian pyramid, time: " << ((getTickCount() - t) / getTickFrequency()) << " sec"); #if ENABLE_LOG t = getTickCount(); #endif // Create the weight map Gaussian pyramid UMat weight_map; std::vector<UMat> weight_pyr_gauss(num_bands_ + 1); if(weight_type_ == CV_32F) { mask.getUMat().convertTo(weight_map, CV_32F, 1./255.); } else // weight_type_ == CV_16S { mask.getUMat().convertTo(weight_map, CV_16S); UMat add_mask; compare(mask, 0, add_mask, CMP_NE); add(weight_map, Scalar::all(1), weight_map, add_mask); } copyMakeBorder(weight_map, weight_pyr_gauss[0], top, bottom, left, right, BORDER_CONSTANT); for (int i = 0; i < num_bands_; ++i) pyrDown(weight_pyr_gauss[i], weight_pyr_gauss[i + 1]); LOGLN(" Create the weight map Gaussian pyramid, time: " << ((getTickCount() - t) / getTickFrequency()) << " sec"); #if ENABLE_LOG t = getTickCount(); #endif int y_tl = tl_new.y - dst_roi_.y; int y_br = br_new.y - dst_roi_.y; int x_tl = tl_new.x - dst_roi_.x; int x_br = br_new.x - dst_roi_.x; // Add weighted layer of the source image to the final Laplacian pyramid layer for (int i = 0; i <= num_bands_; ++i) { Rect rc(x_tl, y_tl, x_br - x_tl, y_br - y_tl); #ifdef HAVE_OPENCL if ( !cv::ocl::useOpenCL() || !ocl_MultiBandBlender_feed(src_pyr_laplace[i], weight_pyr_gauss[i], dst_pyr_laplace_[i](rc), dst_band_weights_[i](rc)) ) #endif { Mat _src_pyr_laplace = src_pyr_laplace[i].getMat(ACCESS_READ); Mat _dst_pyr_laplace = dst_pyr_laplace_[i](rc).getMat(ACCESS_RW); Mat _weight_pyr_gauss = weight_pyr_gauss[i].getMat(ACCESS_READ); Mat _dst_band_weights = dst_band_weights_[i](rc).getMat(ACCESS_RW); if(weight_type_ == CV_32F) { for (int y = 0; y < rc.height; ++y) { const Point3_<short>* src_row = _src_pyr_laplace.ptr<Point3_<short> >(y); Point3_<short>* dst_row = _dst_pyr_laplace.ptr<Point3_<short> >(y); const float* weight_row = _weight_pyr_gauss.ptr<float>(y); float* dst_weight_row = _dst_band_weights.ptr<float>(y); for (int x = 0; x < rc.width; ++x) { dst_row[x].x += static_cast<short>(src_row[x].x * weight_row[x]); dst_row[x].y += static_cast<short>(src_row[x].y * weight_row[x]); dst_row[x].z += static_cast<short>(src_row[x].z * weight_row[x]); dst_weight_row[x] += weight_row[x]; } } } else // weight_type_ == CV_16S { for (int y = 0; y < y_br - y_tl; ++y) { const Point3_<short>* src_row = _src_pyr_laplace.ptr<Point3_<short> >(y); Point3_<short>* dst_row = _dst_pyr_laplace.ptr<Point3_<short> >(y); const short* weight_row = _weight_pyr_gauss.ptr<short>(y); short* dst_weight_row = _dst_band_weights.ptr<short>(y); for (int x = 0; x < x_br - x_tl; ++x) { dst_row[x].x += short((src_row[x].x * weight_row[x]) >> 8); dst_row[x].y += short((src_row[x].y * weight_row[x]) >> 8); dst_row[x].z += short((src_row[x].z * weight_row[x]) >> 8); dst_weight_row[x] += weight_row[x]; } } } } #ifdef HAVE_OPENCL else {
void cv::goodFeaturesToTrack( InputArray _image, OutputArray _corners, int maxCorners, double qualityLevel, double minDistance, InputArray _mask, int blockSize, bool useHarrisDetector, double harrisK ) { Mat image = _image.getMat(), mask = _mask.getMat(); CV_Assert( qualityLevel > 0 && minDistance >= 0 && maxCorners >= 0 ); CV_Assert( mask.empty() || (mask.type() == CV_8UC1 && mask.size() == image.size()) ); Mat eig, tmp; if( useHarrisDetector ) cornerHarris( image, eig, blockSize, 3, harrisK ); else cornerMinEigenVal( image, eig, blockSize, 3 ); double maxVal = 0; minMaxLoc( eig, 0, &maxVal, 0, 0, mask ); threshold( eig, eig, maxVal*qualityLevel, 0, THRESH_TOZERO ); dilate( eig, tmp, Mat()); Size imgsize = image.size(); vector<const float*> tmpCorners; // collect list of pointers to features - put them into temporary image for( int y = 1; y < imgsize.height - 1; y++ ) { const float* eig_data = (const float*)eig.ptr(y); const float* tmp_data = (const float*)tmp.ptr(y); const uchar* mask_data = mask.data ? mask.ptr(y) : 0; for( int x = 1; x < imgsize.width - 1; x++ ) { float val = eig_data[x]; if( val != 0 && val == tmp_data[x] && (!mask_data || mask_data[x]) ) tmpCorners.push_back(eig_data + x); } } sort( tmpCorners, greaterThanPtr<float>() ); vector<Point2f> corners; size_t i, j, total = tmpCorners.size(), ncorners = 0; if(minDistance >= 1) { // Partition the image into larger grids int w = image.cols; int h = image.rows; const int cell_size = cvRound(minDistance); const int grid_width = (w + cell_size - 1) / cell_size; const int grid_height = (h + cell_size - 1) / cell_size; std::vector<std::vector<Point2f> > grid(grid_width*grid_height); minDistance *= minDistance; for( i = 0; i < total; i++ ) { int ofs = (int)((const uchar*)tmpCorners[i] - eig.data); int y = (int)(ofs / eig.step); int x = (int)((ofs - y*eig.step)/sizeof(float)); bool good = true; int x_cell = x / cell_size; int y_cell = y / cell_size; int x1 = x_cell - 1; int y1 = y_cell - 1; int x2 = x_cell + 1; int y2 = y_cell + 1; // boundary check x1 = std::max(0, x1); y1 = std::max(0, y1); x2 = std::min(grid_width-1, x2); y2 = std::min(grid_height-1, y2); for( int yy = y1; yy <= y2; yy++ ) { for( int xx = x1; xx <= x2; xx++ ) { vector <Point2f> &m = grid[yy*grid_width + xx]; if( m.size() ) { for(j = 0; j < m.size(); j++) { float dx = x - m[j].x; float dy = y - m[j].y; if( dx*dx + dy*dy < minDistance ) { good = false; goto break_out; } } } } } break_out: if(good) { // printf("%d: %d %d -> %d %d, %d, %d -- %d %d %d %d, %d %d, c=%d\n", // i,x, y, x_cell, y_cell, (int)minDistance, cell_size,x1,y1,x2,y2, grid_width,grid_height,c); grid[y_cell*grid_width + x_cell].push_back(Point2f((float)x, (float)y)); corners.push_back(Point2f((float)x, (float)y)); ++ncorners; if( maxCorners > 0 && (int)ncorners == maxCorners ) break; } } } else { for( i = 0; i < total; i++ ) { int ofs = (int)((const uchar*)tmpCorners[i] - eig.data); int y = (int)(ofs / eig.step); int x = (int)((ofs - y*eig.step)/sizeof(float)); corners.push_back(Point2f((float)x, (float)y)); ++ncorners; if( maxCorners > 0 && (int)ncorners == maxCorners ) break; } } Mat(corners).convertTo(_corners, _corners.fixedType() ? _corners.type() : CV_32F); /* for( i = 0; i < total; i++ ) { int ofs = (int)((const uchar*)tmpCorners[i] - eig.data); int y = (int)(ofs / eig.step); int x = (int)((ofs - y*eig.step)/sizeof(float)); if( minDistance > 0 ) { for( j = 0; j < ncorners; j++ ) { float dx = x - corners[j].x; float dy = y - corners[j].y; if( dx*dx + dy*dy < minDistance ) break; } if( j < ncorners ) continue; } corners.push_back(Point2f((float)x, (float)y)); ++ncorners; if( maxCorners > 0 && (int)ncorners == maxCorners ) break; } */ }
double cv::kmeans( InputArray _data, int K, InputOutputArray _bestLabels, TermCriteria criteria, int attempts, int flags, OutputArray _centers ) { const int SPP_TRIALS = 3; Mat data0 = _data.getMat(); bool isrow = data0.rows == 1; int N = isrow ? data0.cols : data0.rows; int dims = (isrow ? 1 : data0.cols)*data0.channels(); int type = data0.depth(); attempts = std::max(attempts, 1); CV_Assert( data0.dims <= 2 && type == CV_32F && K > 0 ); CV_Assert( N >= K ); Mat data(N, dims, CV_32F, data0.ptr(), isrow ? dims * sizeof(float) : static_cast<size_t>(data0.step)); _bestLabels.create(N, 1, CV_32S, -1, true); Mat _labels, best_labels = _bestLabels.getMat(); if( flags & CV_KMEANS_USE_INITIAL_LABELS ) { CV_Assert( (best_labels.cols == 1 || best_labels.rows == 1) && best_labels.cols*best_labels.rows == N && best_labels.type() == CV_32S && best_labels.isContinuous()); best_labels.copyTo(_labels); } else { if( !((best_labels.cols == 1 || best_labels.rows == 1) && best_labels.cols*best_labels.rows == N && best_labels.type() == CV_32S && best_labels.isContinuous())) best_labels.create(N, 1, CV_32S); _labels.create(best_labels.size(), best_labels.type()); } int* labels = _labels.ptr<int>(); Mat centers(K, dims, type), old_centers(K, dims, type), temp(1, dims, type); std::vector<int> counters(K); std::vector<Vec2f> _box(dims); Vec2f* box = &_box[0]; double best_compactness = DBL_MAX, compactness = 0; RNG& rng = theRNG(); int a, iter, i, j, k; if( criteria.type & TermCriteria::EPS ) criteria.epsilon = std::max(criteria.epsilon, 0.); else criteria.epsilon = FLT_EPSILON; criteria.epsilon *= criteria.epsilon; if( criteria.type & TermCriteria::COUNT ) criteria.maxCount = std::min(std::max(criteria.maxCount, 2), 100); else criteria.maxCount = 100; if( K == 1 ) { attempts = 1; criteria.maxCount = 2; } const float* sample = data.ptr<float>(0); for( j = 0; j < dims; j++ ) box[j] = Vec2f(sample[j], sample[j]); for( i = 1; i < N; i++ ) { sample = data.ptr<float>(i); for( j = 0; j < dims; j++ ) { float v = sample[j]; box[j][0] = std::min(box[j][0], v); box[j][1] = std::max(box[j][1], v); } } for( a = 0; a < attempts; a++ ) { double max_center_shift = DBL_MAX; for( iter = 0;; ) { swap(centers, old_centers); if( iter == 0 && (a > 0 || !(flags & KMEANS_USE_INITIAL_LABELS)) ) { if( flags & KMEANS_PP_CENTERS ) generateCentersPP(data, centers, K, rng, SPP_TRIALS); else { for( k = 0; k < K; k++ ) generateRandomCenter(_box, centers.ptr<float>(k), rng); } } else { if( iter == 0 && a == 0 && (flags & KMEANS_USE_INITIAL_LABELS) ) { for( i = 0; i < N; i++ ) CV_Assert( (unsigned)labels[i] < (unsigned)K ); } // compute centers centers = Scalar(0); for( k = 0; k < K; k++ ) counters[k] = 0; for( i = 0; i < N; i++ ) { sample = data.ptr<float>(i); k = labels[i]; float* center = centers.ptr<float>(k); j=0; #if CV_ENABLE_UNROLLED for(; j <= dims - 4; j += 4 ) { float t0 = center[j] + sample[j]; float t1 = center[j+1] + sample[j+1]; center[j] = t0; center[j+1] = t1; t0 = center[j+2] + sample[j+2]; t1 = center[j+3] + sample[j+3]; center[j+2] = t0; center[j+3] = t1; } #endif for( ; j < dims; j++ ) center[j] += sample[j]; counters[k]++; } if( iter > 0 ) max_center_shift = 0; for( k = 0; k < K; k++ ) { if( counters[k] != 0 ) continue; // if some cluster appeared to be empty then: // 1. find the biggest cluster // 2. find the farthest from the center point in the biggest cluster // 3. exclude the farthest point from the biggest cluster and form a new 1-point cluster. int max_k = 0; for( int k1 = 1; k1 < K; k1++ ) { if( counters[max_k] < counters[k1] ) max_k = k1; } double max_dist = 0; int farthest_i = -1; float* new_center = centers.ptr<float>(k); float* old_center = centers.ptr<float>(max_k); float* _old_center = temp.ptr<float>(); // normalized float scale = 1.f/counters[max_k]; for( j = 0; j < dims; j++ ) _old_center[j] = old_center[j]*scale; for( i = 0; i < N; i++ ) { if( labels[i] != max_k ) continue; sample = data.ptr<float>(i); double dist = normL2Sqr(sample, _old_center, dims); if( max_dist <= dist ) { max_dist = dist; farthest_i = i; } } counters[max_k]--; counters[k]++; labels[farthest_i] = k; sample = data.ptr<float>(farthest_i); for( j = 0; j < dims; j++ ) { old_center[j] -= sample[j]; new_center[j] += sample[j]; } } for( k = 0; k < K; k++ ) { float* center = centers.ptr<float>(k); CV_Assert( counters[k] != 0 ); float scale = 1.f/counters[k]; for( j = 0; j < dims; j++ ) center[j] *= scale; if( iter > 0 ) { double dist = 0; const float* old_center = old_centers.ptr<float>(k); for( j = 0; j < dims; j++ ) { double t = center[j] - old_center[j]; dist += t*t; } max_center_shift = std::max(max_center_shift, dist); } } } if( ++iter == MAX(criteria.maxCount, 2) || max_center_shift <= criteria.epsilon ) break; // assign labels Mat dists(1, N, CV_64F); double* dist = dists.ptr<double>(0); parallel_for_(Range(0, N), KMeansDistanceComputer(dist, labels, data, centers)); compactness = 0; for( i = 0; i < N; i++ ) { compactness += dist[i]; } } if( compactness < best_compactness ) { best_compactness = compactness; if( _centers.needed() ) centers.copyTo(_centers); _labels.copyTo(best_labels); } } return best_compactness; }
void crossCorr( const Mat& img, const Mat& _templ, Mat& corr, Size corrsize, int ctype, Point anchor, double delta, int borderType ) { const double blockScale = 4.5; const int minBlockSize = 256; std::vector<uchar> buf; Mat templ = _templ; int depth = img.depth(), cn = img.channels(); int tdepth = templ.depth(), tcn = templ.channels(); int cdepth = CV_MAT_DEPTH(ctype), ccn = CV_MAT_CN(ctype); CV_Assert( img.dims <= 2 && templ.dims <= 2 && corr.dims <= 2 ); if( depth != tdepth && tdepth != std::max(CV_32F, depth) ) { _templ.convertTo(templ, std::max(CV_32F, depth)); tdepth = templ.depth(); } CV_Assert( depth == tdepth || tdepth == CV_32F); CV_Assert( corrsize.height <= img.rows + templ.rows - 1 && corrsize.width <= img.cols + templ.cols - 1 ); CV_Assert( ccn == 1 || delta == 0 ); corr.create(corrsize, ctype); int maxDepth = depth > CV_8S ? CV_64F : std::max(std::max(CV_32F, tdepth), cdepth); Size blocksize, dftsize; blocksize.width = cvRound(templ.cols*blockScale); blocksize.width = std::max( blocksize.width, minBlockSize - templ.cols + 1 ); blocksize.width = std::min( blocksize.width, corr.cols ); blocksize.height = cvRound(templ.rows*blockScale); blocksize.height = std::max( blocksize.height, minBlockSize - templ.rows + 1 ); blocksize.height = std::min( blocksize.height, corr.rows ); dftsize.width = std::max(getOptimalDFTSize(blocksize.width + templ.cols - 1), 2); dftsize.height = getOptimalDFTSize(blocksize.height + templ.rows - 1); if( dftsize.width <= 0 || dftsize.height <= 0 ) CV_Error( CV_StsOutOfRange, "the input arrays are too big" ); // recompute block size blocksize.width = dftsize.width - templ.cols + 1; blocksize.width = MIN( blocksize.width, corr.cols ); blocksize.height = dftsize.height - templ.rows + 1; blocksize.height = MIN( blocksize.height, corr.rows ); Mat dftTempl( dftsize.height*tcn, dftsize.width, maxDepth ); Mat dftImg( dftsize, maxDepth ); int i, k, bufSize = 0; if( tcn > 1 && tdepth != maxDepth ) bufSize = templ.cols*templ.rows*CV_ELEM_SIZE(tdepth); if( cn > 1 && depth != maxDepth ) bufSize = std::max( bufSize, (blocksize.width + templ.cols - 1)* (blocksize.height + templ.rows - 1)*CV_ELEM_SIZE(depth)); if( (ccn > 1 || cn > 1) && cdepth != maxDepth ) bufSize = std::max( bufSize, blocksize.width*blocksize.height*CV_ELEM_SIZE(cdepth)); buf.resize(bufSize); // compute DFT of each template plane for( k = 0; k < tcn; k++ ) { int yofs = k*dftsize.height; Mat src = templ; Mat dst(dftTempl, Rect(0, yofs, dftsize.width, dftsize.height)); Mat dst1(dftTempl, Rect(0, yofs, templ.cols, templ.rows)); if( tcn > 1 ) { src = tdepth == maxDepth ? dst1 : Mat(templ.size(), tdepth, &buf[0]); int pairs[] = {k, 0}; mixChannels(&templ, 1, &src, 1, pairs, 1); } if( dst1.data != src.data ) src.convertTo(dst1, dst1.depth()); if( dst.cols > templ.cols ) { Mat part(dst, Range(0, templ.rows), Range(templ.cols, dst.cols)); part = Scalar::all(0); } dft(dst, dst, 0, templ.rows); } int tileCountX = (corr.cols + blocksize.width - 1)/blocksize.width; int tileCountY = (corr.rows + blocksize.height - 1)/blocksize.height; int tileCount = tileCountX * tileCountY; Size wholeSize = img.size(); Point roiofs(0,0); Mat img0 = img; if( !(borderType & BORDER_ISOLATED) ) { img.locateROI(wholeSize, roiofs); img0.adjustROI(roiofs.y, wholeSize.height-img.rows-roiofs.y, roiofs.x, wholeSize.width-img.cols-roiofs.x); } borderType |= BORDER_ISOLATED; // calculate correlation by blocks for( i = 0; i < tileCount; i++ ) { int x = (i%tileCountX)*blocksize.width; int y = (i/tileCountX)*blocksize.height; Size bsz(std::min(blocksize.width, corr.cols - x), std::min(blocksize.height, corr.rows - y)); Size dsz(bsz.width + templ.cols - 1, bsz.height + templ.rows - 1); int x0 = x - anchor.x + roiofs.x, y0 = y - anchor.y + roiofs.y; int x1 = std::max(0, x0), y1 = std::max(0, y0); int x2 = std::min(img0.cols, x0 + dsz.width); int y2 = std::min(img0.rows, y0 + dsz.height); Mat src0(img0, Range(y1, y2), Range(x1, x2)); Mat dst(dftImg, Rect(0, 0, dsz.width, dsz.height)); Mat dst1(dftImg, Rect(x1-x0, y1-y0, x2-x1, y2-y1)); Mat cdst(corr, Rect(x, y, bsz.width, bsz.height)); for( k = 0; k < cn; k++ ) { Mat src = src0; dftImg = Scalar::all(0); if( cn > 1 ) { src = depth == maxDepth ? dst1 : Mat(y2-y1, x2-x1, depth, &buf[0]); int pairs[] = {k, 0}; mixChannels(&src0, 1, &src, 1, pairs, 1); } if( dst1.data != src.data ) src.convertTo(dst1, dst1.depth()); if( x2 - x1 < dsz.width || y2 - y1 < dsz.height ) copyMakeBorder(dst1, dst, y1-y0, dst.rows-dst1.rows-(y1-y0), x1-x0, dst.cols-dst1.cols-(x1-x0), borderType); dft( dftImg, dftImg, 0, dsz.height ); Mat dftTempl1(dftTempl, Rect(0, tcn > 1 ? k*dftsize.height : 0, dftsize.width, dftsize.height)); mulSpectrums(dftImg, dftTempl1, dftImg, 0, true); dft( dftImg, dftImg, DFT_INVERSE + DFT_SCALE, bsz.height ); src = dftImg(Rect(0, 0, bsz.width, bsz.height)); if( ccn > 1 ) { if( cdepth != maxDepth ) { Mat plane(bsz, cdepth, &buf[0]); src.convertTo(plane, cdepth, 1, delta); src = plane; } int pairs[] = {0, k}; mixChannels(&src, 1, &cdst, 1, pairs, 1); } else { if( k == 0 ) src.convertTo(cdst, cdepth, 1, delta); else { if( maxDepth != cdepth ) { Mat plane(bsz, cdepth, &buf[0]); src.convertTo(plane, cdepth); src = plane; } add(src, cdst, cdst); } } } } }