void SecondOrderOptimizeFusionMove::optimize(Depth &result, const int max_iter) const { vector<Depth> proposals; genProposal(proposals); //proposals.push_back(noisyDisp); char buffer[1024] = {}; //initialize by random result.initialize(width, height, -1); const int nLabel = model->nLabel; std::default_random_engine generator; std::uniform_int_distribution<int> distribution(0, nLabel - 1); for (auto i = 0; i < width * height; ++i) { //result.setDepthAtInd(i, (double) distribution(generator)); //result.setDepthAtInd(i, noisyDisp[i]); result[i] = 0; } sprintf(buffer, "%s/temp/init_result.jpg", file_io.getDirectory().c_str()); result.saveImage(buffer, 256.0 / (double)nLabel); list<double> diffE; double lastEnergy = evaluateEnergy(result); double initialEnergy = lastEnergy; int iter = 0; const double termination = 0.1; float timming = (float) getTickCount(); const int smoothInterval = 5; while (true) { if (iter == max_iter) break; cout << "======================" << endl; Depth newProposal; // if (iter > 0 && iter % smoothInterval == 0) { // Depth orip1; // newProposal.initialize(width, height, -1); // orip1.initialize(width, height, -1); // for (auto i = 0; i < width * height; ++i) { // orip1.setDepthAtInd(i, result[i]); // newProposal.setDepthAtInd(i, result[i]); // } // int direction = iter / smoothInterval; // if (direction % 2 == 0) { // //horizontally // for (auto y = 0; y < height; ++y) { // for (auto x = 1; x < width - 1; ++x) // newProposal.setDepthAtInt(x, y, (orip1(x + 1, y) + orip1(x - 1, y)) / 2); // newProposal.setDepthAtInt(width - 1, y, orip1(width - 1, y)); // } // } else { // //vertically // for (auto x = 0; x < width; ++x) { // for (auto y = 1; y < height - 1; ++y) // newProposal.setDepthAtInt(x, y, (orip1(x, y + 1) + orip1(x, y - 1)) / 2); // newProposal.setDepthAtInt(x, height - 1, orip1(x, height - 1)); // } // } // cout << "Iteration " << iter << " using smoothing proposal " << endl; // } else { // } newProposal = proposals[iter % (proposals.size())]; printf("Fusing with proposal %d\n", (int)(iter % proposals.size())); //after several iteration, smooth the dispartiy fusionMove(result, newProposal); double e = evaluateEnergy(result); double energyDiff = lastEnergy - e; if (diffE.size() >= average_over) diffE.pop_front(); diffE.push_back(energyDiff); double average_diffe = std::accumulate(diffE.begin(), diffE.end(), 0.0) / (double) diffE.size(); printf("Done. Final energy: %.5f, energy decrease: %.5f average decrease: %.5f\n", e, energyDiff, average_diffe); lastEnergy = e; sprintf(buffer, "%s/temp/fusionmove_iter%05d.jpg", file_io.getDirectory().c_str(), iter); result.saveImage(buffer, 256.0 / (double) nLabel); if (iter > proposals.size() * 2 && average_diffe < termination) { cout << "Converge!" << endl; break; } iter++; } timming = ((float) getTickCount() - timming) / (float) getTickFrequency(); printf("All done. Initial energy: %.5f, final energy: %.5f, time usage: %.2fs\n", initialEnergy, lastEnergy, timming); }
void DynamicConfidence::run(const int anchor, Depth &confidence) { const int framenum = file_io.getTotalNum(); CHECK_LT(anchor, framenum); const int startid = anchor - max_tWindow / 2 >= 0 ? anchor - max_tWindow / 2 : 0; const int endid = anchor + max_tWindow / 2 < framenum ? anchor + max_tWindow / 2 : framenum - 1; char buffer[1024] = {}; vector<FlowFrame> flow_forward((size_t) endid - startid + 1); vector<FlowFrame> flow_backward((size_t) endid - startid + 1); printf("=====================\nFrame: %d\n", anchor); cout << "Reading optical flow..." << endl; for (auto i = startid; i <= endid; ++i) { cout << '.' << flush; if (i < file_io.getTotalNum() - 1) flow_forward[i - startid].readFlowFile(file_io.getOpticalFlow_forward(i)); if (i > 0) flow_backward[i - startid].readFlowFile(file_io.getOpticalFlow_backward(i)); } cout << endl; const int width = (int)(flow_forward[0].width() / downsample); const int height = (int)(flow_forward[0].height() / downsample); const int widthFull = flow_forward[0].width(); const int heightFull = flow_forward[0].height(); Depth confidence_down(width, height, -1); confidence.initialize(widthFull, heightFull, 0); const int min_interval = 0; const double kth_ratio = 0.8; const size_t min_length = 5; double min_depth, max_depth; cout << "Computing min-max depth" << endl; computeMinMaxDepth(anchor, min_depth, max_depth); const int id = anchor - startid; const theia::Camera& refCam = reconstruction.View(orderedId[anchor].second)->Camera(); cout << "Computing confidence..." << endl; const int unit = width * height / 10; const int testx = 1596 / downsample; const int testy = 472 / downsample; int startx = 0, endx = width-1, starty = 0, endy = height-1; if(testx >=0 && testy>=0){ printf("Debug mode: %d, %d\n", testx, testy); startx = testx; endx = testx; starty = testy; endy = testy; } double max_line_length = 100; for (auto y = starty; y<= endy; ++y) { for (auto x = startx; x <= endx; ++x) { if((y*width+x) % unit == 0) cout << '.' << flush; vector<double> epiErr; Vector2d locL((double) x, (double) y); Vector3d ray = refCam.PixelToUnitDepthRay(locL * downsample); Vector3d minpt = refCam.GetPosition() + ray * min_depth; Vector3d maxpt = refCam.GetPosition() + ray * max_depth; if(testx >= 0 && testy >= 0){ printf("min depth: %.3f, max depth: %.3f\n", min_depth, max_depth); } for (auto i = 0; i < flow_forward.size(); ++i) { const theia::Camera& cam2 = reconstruction.View(orderedId[i+startid].second)->Camera(); if(i == id){ Mat img = imread(file_io.getImage(i+startid)); cv::circle(img, cv::Point(locL[0], locL[1]), 2, cv::Scalar(0,0,255), 2); sprintf(buffer, "%s/temp/conf_ref%05d_%05d.jpg", file_io.getDirectory().c_str(), anchor, i+startid); imwrite(buffer, img); continue; } if (std::abs(id - i) < min_interval) continue; Vector2d locR; if (id < i) { if (!flow_util::trackPoint(locL * downsample, flow_forward, id, i, locR)) continue; } else { if (!flow_util::trackPoint(locL * downsample, flow_backward, id, i, locR)) continue; } Vector2d spt, ept; cam2.ProjectPoint(minpt.homogeneous(), &spt); cam2.ProjectPoint(maxpt.homogeneous(), &ept); // Vector2d dir = spt - ept; // dir.normalize(); // spt = ept + dir * max_line_length; if(x == testx && y == testy){ Mat img = imread(file_io.getImage(i+startid)); cv::circle(img, cv::Point(locR[0], locR[1]), 2, cv::Scalar(0,0,255), 2); printf("---------------------\nFrame %d, spt:(%.2f,%.2f), ept:(%.2f,%.2f)\n", i+startid, spt[0], spt[1], ept[0], ept[1]); cv::line(img, cv::Point(spt[0], spt[1]), cv::Point(ept[0], ept[1]), cv::Scalar(255,0,0), 2); sprintf(buffer, "%s/temp/conf_ref%05d_%05d.jpg", file_io.getDirectory().c_str(), anchor, i+startid); imwrite(buffer, img); theia::Matrix3x4d pMatrix; cam2.GetProjectionMatrix(&pMatrix); cout << "Projection matrix:" << endl << pMatrix << endl; } epiErr.push_back(geometry_util::distanceToLineSegment<2>(locR, spt, ept)); } if (epiErr.size() < min_length) { confidence(x, y) = 0.0; continue; } const size_t kth = (size_t) (epiErr.size() * kth_ratio); nth_element(epiErr.begin(), epiErr.begin() + kth, epiErr.end()); confidence_down.setDepthAtInt(x, y, epiErr[kth]); } } cout << endl; //upsample to original resolution for(auto x=0; x<widthFull-downsample; ++x){ for(auto y=0; y<heightFull-downsample; ++y) confidence(x,y) = confidence_down.getDepthAt(Vector2d((double)x/downsample, (double)y/downsample)); } confidence.updateStatics(); }