| 701 | |
| 702 | template <int C, int H, int W> |
| 703 | void writePPMFileWithBBox(const std::string& filename, PPM<C, H, W>& ppm, const BBox& bbox) |
| 704 | { |
| 705 | std::ofstream outfile("./" + filename, std::ofstream::binary); |
| 706 | assert(!outfile.fail()); |
| 707 | outfile << "P6" |
| 708 | << "\n" |
| 709 | << ppm.w << " " << ppm.h << "\n" |
| 710 | << ppm.max << "\n"; |
| 711 | |
| 712 | auto round = [](float x) -> int { return int(std::floor(x + 0.5F)); }; |
| 713 | const int x1 = std::min(std::max(0, round(int(bbox.x1))), W - 1); |
| 714 | const int x2 = std::min(std::max(0, round(int(bbox.x2))), W - 1); |
| 715 | const int y1 = std::min(std::max(0, round(int(bbox.y1))), H - 1); |
| 716 | const int y2 = std::min(std::max(0, round(int(bbox.y2))), H - 1); |
| 717 | |
| 718 | for (int x = x1; x <= x2; ++x) |
| 719 | { |
| 720 | // bbox top border |
| 721 | ppm.buffer[(y1 * ppm.w + x) * 3] = 255; |
| 722 | ppm.buffer[(y1 * ppm.w + x) * 3 + 1] = 0; |
| 723 | ppm.buffer[(y1 * ppm.w + x) * 3 + 2] = 0; |
| 724 | // bbox bottom border |
| 725 | ppm.buffer[(y2 * ppm.w + x) * 3] = 255; |
| 726 | ppm.buffer[(y2 * ppm.w + x) * 3 + 1] = 0; |
| 727 | ppm.buffer[(y2 * ppm.w + x) * 3 + 2] = 0; |
| 728 | } |
| 729 | |
| 730 | for (int y = y1; y <= y2; ++y) |
| 731 | { |
| 732 | // bbox left border |
| 733 | ppm.buffer[(y * ppm.w + x1) * 3] = 255; |
| 734 | ppm.buffer[(y * ppm.w + x1) * 3 + 1] = 0; |
| 735 | ppm.buffer[(y * ppm.w + x1) * 3 + 2] = 0; |
| 736 | // bbox right border |
| 737 | ppm.buffer[(y * ppm.w + x2) * 3] = 255; |
| 738 | ppm.buffer[(y * ppm.w + x2) * 3 + 1] = 0; |
| 739 | ppm.buffer[(y * ppm.w + x2) * 3 + 2] = 0; |
| 740 | } |
| 741 | |
| 742 | outfile.write(reinterpret_cast<char*>(ppm.buffer), ppm.w * ppm.h * 3); |
| 743 | } |
| 744 | |
| 745 | inline void writePPMFileWithBBox(const std::string& filename, vPPM ppm, std::vector<BBox>& dets) |
| 746 | { |