//! Get pair of matricies if present bool pop_if_present( pair<Matrix2x2, Matrix2x2> &mm ) { // get first matrix if present if(!Queue.try_pop(mm.first)) return false; // get second matrix if present if(!Queue.try_pop(mm.second)) { // if not, then push back first matrix Queue.push(mm.first); return false; } return true; }
int main(int argc, char*argv[]) { size_t nElements = 1280000; size_t nthreads = 1; struct timeval start, stop; if (argc >= 2) { nthreads = atoi(argv[1]); } if (argc >= 3) { nElements = atoi(argv[2]); } if (argc >= 4) { objsize = atoi(argv[3]); } task_scheduler_init init(nthreads); for (uintptr_t i = 0; i < nElements; i++) { cq.push((void*)i); } for (uintptr_t i = 0; i < nElements; i++) { void* j; cq.try_pop(j); assert(i == (uintptr_t)j); } assert(cq.empty()); tick_count t0 = tick_count::now(); parallel_for(blocked_range<size_t>(0, nElements), loop_queuer()); tick_count t1 = tick_count::now(); printf("queue time: %f secs\n", (t1 - t0).seconds()); t0 = tick_count::now(); parallel_for(blocked_range<size_t>(0, nElements), loop_dequeuer()); t1 = tick_count::now(); printf("dequeue time: %f secs\n", (t1 - t0).seconds()); assert(cq.empty()); t0 = tick_count::now(); parallel_for(blocked_range<size_t>(0, nElements), loop_queuer()); parallel_for(blocked_range<size_t>(0, nElements), loop_dequeuer()); t1 = tick_count::now(); printf("both time: %f secs\n", (t1 - t0).seconds()); assert(cq.empty()); printf("success!\n"); return 0; }
void writefn(std::string outaudio, std::string outdiff) { std::ofstream oaudio(outaudio, std::ios::binary); //int fourcc = CV_FOURCC('4', '6', '2', 'H'); int fourcc = -1; std::cout << "creating VideoWriter\n"; std::cout << "fps " << vid_fps << ", reduction " << reduction << "\n"; cv::VideoWriter odiff(outdiff.c_str(), fourcc, vid_fps / reduction, cv::Size(width, height), true); //cv::VideoWriter omask(outmask.c_str(), fourcc, vid_fps / reduction, cv::Size(width, height), true); std::cout << "done creating VideoWriter\n"; WriteElement element; while (true) { bool rv = writequeue.try_pop(element); if (!rv) continue; if (element.done) break; // video odiff.write(element.mat); // audio int u = (int)iround(audiorate * (element.frameno + 0) / (vid_fps / reduction)); int v = (int)iround(audiorate * (element.frameno + 1) / (vid_fps / reduction)); int nsamples = v - u; std::vector<int16_t> samples(nsamples, 0); for (int k = 0; k < nsamples; k += 1) samples[k] = sin(audiofreq * 2 * M_PI / audiorate * (u + k)) * ((1<<15)-1) * linmap(20 * log10(element.masksum), -90.0, 0.0, 0.0, 1.0); oaudio.write((char*)samples.data(), sizeof(samples[0]) * nsamples); } odiff.release(); oaudio.close(); std::cout << "writer is done\n"; }
void operator() (const blocked_range<size_t>&r) const { size_t begin = r.begin(); size_t end = r.end(); void * ref = tbballoc.allocate(1); memset(ref, 1, objsize); for (size_t i = begin; i < end; i++) { void* j; cq.try_pop(j); assert(NULL != j); if (memcmp(ref, j, objsize)) { fprintf(stderr, "memory was corrupted!\n"); exit(-3); } tbballoc.deallocate((bigobj<1024>*)j, 0); } }
int main(int argc, char **argv) { /* cv::Mat foo(50,1, CV_32FC3); cv::Mat bar(3,1, CV_32FC1); cv::Mat baz = bar.t() * foo.reshape(1).t(); cout << baz.size() << endl; return 0; //*/ parse_args(argc, argv); if (videofile.empty()) { std::cout << "no input file given" << std::endl; return 0; } auto vid = new cv::VideoCapture(videofile); if (!vid->isOpened()) { std::cerr << "vid could not be opened!" << std::endl; delete vid; exit(1); } // build file names char buf[1000]; std::string basename = splitext(videofile); sprintf_s(buf, "%s-foreground-r%d%s-b%dx%d-a%g-d%g-s%g-mst%g", basename.c_str(), reduction, (blendframes ? "b" : ""), blur.x, blur.y, alpha_avg, alpha_dev, sigma_dev, masksum_threshold ); std::string outbase(buf); if (suffix.length() > 0) outbase += "-" + suffix; std::cout << "outbase: " << outbase << std::endl; std::string inmaskname(basename + "-inmask.bmp"); cv::Mat inmask = cv::imread(inmaskname, cv::IMREAD_GRAYSCALE); bool const use_inmask = (inmask.data != NULL); if (use_inmask) { std::cout << "using inmask " << inmaskname << std::endl; //cv::imshow("inmask", inmask); } std::string outaudio(outbase + "-audio.raw"); // raw pcm_s16le //std::string outmask (outbase + "-mask.avi"); std::string outdiff (outbase + "-maskdiff.avi"); vid_fps = vid->get(CV_CAP_PROP_FPS); width = (int)vid->get(CV_CAP_PROP_FRAME_WIDTH); height = (int)vid->get(CV_CAP_PROP_FRAME_HEIGHT); nframes = (int)vid->get(CV_CAP_PROP_FRAME_COUNT); if (override_fps) { cout << "fps " << vid_fps << " uncorrected" << endl; cout << "nframes " << nframes << " uncorrected" << endl; // compensate nframes = nframes / vid_fps * override_fps; vid_fps = override_fps; } cout << "fps " << vid_fps << endl; cout << "nframes " << nframes << endl; assert(fmod((double)audiorate, vid_fps) < 1.0); cv::Mat frameu8(height, width, CV_8UC3, cv::Scalar::all(0.0f)); cv::Mat frame(height, width, CV_32FC3, cv::Scalar::all(0.0f)); cv::Mat gray(height, width, CV_32F, cv::Scalar::all(0.0f)); cv::Mat average(height, width, CV_32F, cv::Scalar::all(0.0f)); cv::Mat deviation(height, width, CV_32F, cv::Scalar::all(0.0f)); ValuePlot plot_avg("plot avg", 640, 360, 0, 640, 0, 1, 0.2); ValuePlot plot_diff("plot diff", 640, 360, 0, 640, -0.03, 0.03, 1/256.); ValuePlot plot_absdiff("plot absdiff", 640, 360, 0, 640, -4, 0, 1); plot_absdiff.use_vmap = true; plot_absdiff.vmap = [](float v) { return log10(v); }; ValuePlot plot_dev("plot dev", 640, 360, 0, 640, -4, 0); plot_dev.use_vmap = true; plot_dev.vmap = [](float v) { return log10(v); }; cv::Mat diff(height, width, CV_32F, cv::Scalar::all(0.0f)); cv::Mat absdiff(height, width, CV_32F, cv::Scalar::all(0.0f)); cv::Mat viewdiff(height, width, CV_32F, cv::Scalar::all(0.0f)); cv::Mat mask(height, width, CV_8U, cv::Scalar::all(0)); std::thread reader(readfn, vid); std::thread writer(writefn, outaudio, outdiff); #ifdef WIN32 SetThreadPriority(writer.native_handle(), THREAD_PRIORITY_ABOVE_NORMAL); #endif double sched = hrtimer(); double dsched = 0.25; double statsched = hrtimer(); double dstat = 1.0; double encode_fps = 0.0; double encode_alpha = 0.1; unsigned lastcount = 0, dcount = 0; // DEBUG //dstat = 0.0; for (int k = 0; k < 5; k += 1) donequeue.push(true); while (running) { MatOrNothing item; bool success = framequeue.try_pop(item); if (!success) continue; if (!item.anything) break; // FIXME: compensate for sporadic *fast* whole-image luminance fluctuations (not caught by sigma) donequeue.push(true); frame = item.frame; gray = item.gray; unsigned frameno = item.frameno; if (use_inmask) cv::subtract(gray, average, diff, inmask); else cv::subtract(gray, average, diff); cv::add(diff, 0.5, viewdiff); absdiff = cv::abs(diff); auto diffsum = (cv::sum(absdiff)[0] / (width * height)); // ===================================================================== // TODO: histogram: deviation from 'average', bin size = 0.1, -10..+10, y-log /* a_avg.push_back(cv::sum(diff)[0] / (double)(width * height)); a_dev.push_back(cv::sum(deviation)[0] / (width * height)); while (a_avg.size() > a_depth) a_avg.erase(a_avg.begin()); while (a_dev.size() > a_depth) a_dev.erase(a_dev.begin()); int histwidth = 500; double const emax = 1; double const emin = -2; a_dev.clear(); a_dev.resize(histwidth+1, 0); for (int y = 0; y < diff.rows; y += 1) for (int x = 0; x < diff.cols; x += 1) { int const bin = 100 + (int)(deviation.at<float>(y,x) / 0.001); if (bin < 0) continue; if (bin >= a_dev.size()) continue; a_dev[bin] += 1; } for (int k = 0; k < a_dev.size(); k += 1) a_dev[k] = a_dev[k] ? log10(a_dev[k]) : -1; //*/ // ===================================================================== cv::compare(1 / sigma_dev * absdiff, deviation, mask, CV_CMP_GT); auto masksum = cv::countNonZero(mask) / (double)(width * height); if (masksum > masksum_threshold) mask = 0; //cv::Mat const mix[] = { mask, mask, mask }; //cv::Mat mask3; //cv::merge(mix, 3, mask3); cv::Mat maskviewdiff(height, width, CV_32F, cv::Scalar::all(0.0f)); maskviewdiff.setTo(cv::Scalar::all(0.5f)); viewdiff.copyTo(maskviewdiff, mask); // ===================================================================== /* { cv::Mat foo; foo = 1 - deviation / 0.005; cv::cvtColor(foo, foo, CV_GRAY2BGR); cv::resize(foo, foo, preview_size, 0, 0, CV_INTER_LINEAR); for (double a = -0.1; a <= 0.1; a += 0.01) cv::line(foo, cv::Point(100 + a / 0.001, 200 - 10), cv::Point(100 + a / 0.001, 200 + 10), cv::Scalar::all(0.5), 1); for (int k = 1; k < a_dev.size(); k += 1) cv::line(foo, cv::Point(k - 1, 200 - a_dev[k - 1] / 0.1), cv::Point(k, 200 - a_dev[k] / 0.1), cv::Scalar::all(1), 1); for (int k = 1; k < a_avg.size(); k += 1) cv::line(foo, cv::Point(k - 1, 200 - a_avg[k - 1] / 0.0001), cv::Point(k, 200 - a_avg[k] / 0.0001), cv::Scalar(1, 0, 0), 1); cv::imshow("debug dev", foo); foo = 1 - absdiff / 0.005; cv::resize(foo, foo, preview_size, 0, 0, CV_INTER_LINEAR); cv::imshow("debug diff", foo); } //*/ // ===================================================================== WriteElement const tmp = { false, frameno, maskviewdiff, masksum }; writequeue.push(tmp); if (!headless && sched < hrtimer()) { sched += dsched; cv::Mat tmp; //cv::Mat display = mask3.clone(); mask.convertTo(tmp, CV_32F, 1/255.); std::ostringstream message; message << to_hms(frameno / vid_fps); message << ", #" << frameno << " @ " << vid_fps << " fps"; message << ", mask " << std::fixed << std::setprecision(6) << masksum; message << ", diff " << std::fixed << std::setprecision(6) << diffsum; cv::putText(tmp, message.str(), cv::Point(5, height - 5), CV_FONT_HERSHEY_PLAIN, width / 600, cv::Scalar::all(1.0), width / 600); cv::resize(tmp, tmp, preview_size, 0, 0, CV_INTER_AREA); cv::imshow("mask", tmp); cv::resize(average, tmp, preview_size, 0, 0, CV_INTER_AREA); cv::imshow("average", tmp); cv::log(deviation, tmp); tmp = tmp * (0.3 / log(10)) + 1.0; cv::resize(tmp, tmp, preview_size, 0, 0, CV_INTER_AREA); cv::imshow("deviation", tmp); /* //plot_avg.plot(average); plot_absdiff.plot(absdiff); plot_diff.plot(diff); plot_dev.plot(deviation); //*/ tmp = ((viewdiff - 0.5) * 5) + 0.5; cv::resize(tmp, tmp, preview_size, 0, 0, CV_INTER_AREA); cv::imshow("diff", tmp); cv::resize(maskviewdiff, tmp, preview_size, 0, 0, CV_INTER_AREA); cv::imshow("maskdiff", tmp); while (true) { int key = cv::waitKey(1); if (key == -1) break; if (key == 27) goto STOP; std::cout << "key " << key << " pressed" << std::endl; } } // updates cv::scaleAdd(absdiff - deviation, alpha_dev, deviation, deviation); cv::scaleAdd(diff, alpha_avg, average, average); if (statsched < hrtimer()) { statsched += dstat; dcount = frameno - lastcount; lastcount = frameno; encode_fps = encode_alpha * dcount + (1 - encode_alpha) * encode_fps; double timeleft = (nframes - frameno) / encode_fps; std::cout << "frame " << frameno; std::cout << ", " << std::fixed << std::setprecision(2) << encode_fps << " fps"; std::cout << ", " << std::fixed << std::setprecision(3) << (100. * frameno / nframes) << "%"; std::cout << ", ETA " << std::fixed << std::setprecision(2) << (timeleft / 60) << "min \r"; std::cout.flush(); } } STOP: running = false; WriteElement const tmp = { true }; writequeue.push(tmp); std::cout << std::endl << "done" << std::endl; if (reader.joinable()) reader.join(); if (writer.joinable()) writer.join(); vid->release(); delete vid; //odiff.release(); //omask.release(); //oaudio.close(); return 0; }
void readfn(cv::VideoCapture *vid) { int frameno = (int)vid->get(CV_CAP_PROP_POS_FRAMES); int const width = (int)vid->get(CV_CAP_PROP_FRAME_WIDTH); int const height = (int)vid->get(CV_CAP_PROP_FRAME_HEIGHT); cv::Mat blendedframe, curframe; cv::Mat floatframe; cv::Mat grayframe; blendedframe.create(cv::Size(width, height), CV_16UC3); while (running) { if (!vid->grab()) break; bool do_process = true; if (blendframes) { vid->retrieve(curframe); //curframe.convertTo(curframe, CV_16UC3); /* std::ostringstream label; label << "Frame " << frameno; cv::putText(curframe, label.str(), cv::Point(10, 20 * (frameno % 50)), cv::FONT_HERSHEY_PLAIN, 2, cv::Scalar::all(255), 2); //*/ //std::cerr << "%reduction = " << (frameno % reduction) << std::endl; if (frameno % reduction == 0) blendedframe.setTo(0); //blendedframe = cv::max(blendedframe, curframe); cv::add(blendedframe, curframe, blendedframe, cv::noArray(), CV_16UC3); if (frameno % reduction == reduction - 1) blendedframe.convertTo(floatframe, CV_32FC3, 1.0 / (reduction * 255)); else do_process = false; /* cv::Mat foo; cv::resize(blendedframe, foo, cv::Size(640, 360)); cv::imshow("debug", foo); if (cv::waitKey(100) != -1) exit(0); //*/ //std::cerr << "do_process = " << (do_process) << std::endl; } else { if (frameno % reduction == reduction - 1) { vid->retrieve(curframe); curframe.convertTo(floatframe, CV_32FC3, 1.0 / 255); } else { do_process = false; } } frameno += 1; if (!do_process) continue; // TODO: proper bounded queue... while (running) { bool foo; bool res = donequeue.try_pop(foo); if (res) break; } // frameu8 is ready cv::cvtColor(floatframe, grayframe, CV_BGR2GRAY, 1); cv::blur(grayframe, grayframe, blur); MatOrNothing const tmp = { true, floatframe.clone(), grayframe.clone(), frameno }; framequeue.push(tmp); //std::cout << "pushing frame " << frameno << std::endl; } MatOrNothing const tmp = { false }; framequeue.push(tmp); }