1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
| int median(int a, int b, int c) { return a >= b ? (b >= c ? b : (a >= c ? c : a)) : (a >= c ? a : (b >= c ? c : b)); }
cv::Mat padding(cv::Mat& img, uchar* pads) { cv::Mat img_pad = cv::Mat(cv::Size(img.cols + pads[2] + pads[3], img.rows + pads[0] + pads[1]), img.type()); cv::copyMakeBorder(img, img_pad, pads[0], pads[1], pads[2], pads[3], cv::BORDER_REFLECT); return img_pad; }
void dpc(cv::Mat& src, uchar thres) { clock_t begin = clock(); uchar pads[4] = { 2, 2, 2, 2 }; cv::Mat src_p = padding(src, pads); ushort* p0, * p1, * p2, * p3, * p4, * p5, * p6, * p7, * p8, * p; int grad_h1 = 0, grad_h2 = 0, grad_h3 = 0, grad_v1 = 0, grad_v2 = 0, grad_v3 = 0; int grad_45_1 = 0, grad_45_2 = 0, grad_45_3 = 0, grad_135_1 = 0, grad_135_2 = 0, grad_135_3 = 0; int grad_h = 0, grad_v = 0, grad_45 = 0, grad_135 = 0; std::vector<int> gradient(4, 0); int grad_sum = 0; for (int i = 0; i < src_p.rows - 4; ++i) { std::cout << "\r" << "DPC: "; std::cout << std::setw(6) << std::fixed << std::setprecision(2) << (float)i / (src_p.rows - 2) * 100 << "%"; p0 = src_p.ptr<ushort>(i + 2); p1 = src_p.ptr<ushort>(i); p2 = src_p.ptr<ushort>(i); p3 = src_p.ptr<ushort>(i); p4 = src_p.ptr<ushort>(i + 2); p5 = src_p.ptr<ushort>(i + 2); p6 = src_p.ptr<ushort>(i + 4); p7 = src_p.ptr<ushort>(i + 4); p8 = src_p.ptr<ushort>(i + 4); p = src.ptr<ushort>(i); for (int j = 0; j < src_p.cols - 4; j++) { grad_h1 = abs(p1[j] + p3[j + 4] - 2 * p2[j + 2]); grad_h2 = abs(p4[j] + p5[j + 4] - 2 * p0[j + 2]); grad_h3 = abs(p6[j] + p8[j + 4] - 2 * p7[j + 2]); grad_v1 = abs(p1[j] + p4[j] - 2 * p6[j]); grad_v2 = abs(p2[j + 2] + p7[j + 2] - 2 * p0[j + 2]); grad_v3 = abs(p3[j + 4] + p8[j + 4] - 2 * p5[j + 4]); grad_45_1 = 2 * abs(p2[j + 2] - p4[j]); grad_45_2 = abs(p3[j + 4] + p6[j] - 2 * p0[j + 2]); grad_45_3 = 2 * abs(p5[j + 4] - p7[j + 2]); grad_135_1 = 2 * abs(p2[j + 2] -p5[j + 4]); grad_135_2 = abs(p1[j] + p8[j + 4] - 2 * p0[j + 2]); grad_135_3 = 2 * abs(p4[j] - p7[j + 2]);
grad_h = median(grad_h1, grad_h2, grad_h3); grad_v = median(grad_v1, grad_v2, grad_v3); grad_45 = median(grad_45_1, grad_45_2, grad_45_3); grad_135 = median(grad_135_1, grad_135_2, grad_135_3); gradient = { grad_h, grad_v, grad_45, grad_135 }; auto minPosition = std::min_element(gradient.begin(), gradient.end()); if (minPosition == gradient.begin() && grad_h2 > 4*(grad_h1+grad_h3)) { if (abs(p4[j] - p0[j + 2]) < abs(p0[j + 2] - p5[j + 4])) { p[j] = p4[j] + (p2[j + 2] + p7[j + 2] - p1[j] - p6[j]) / 2; } else { p[j] = p5[j + 4] + (p2[j + 2] + p7[j + 2] - p3[j + 4] - p8[j + 4]) / 2; } } if (minPosition == gradient.begin()+1 && grad_v2 > 4 * (grad_v1 + grad_v3)) { if (abs(p2[j + 2] - p0[j + 2]) < abs(p0[j + 2] - p7[j + 2])) { p[j] = p2[j + 2] + (p4[j] + p5[j + 4] - p1[j] - p3[j + 4]) / 2; } else { p[j] = p7[j + 2] + (p4[j] + p5[j + 4] - p6[j] - p8[j + 4]) / 2; } } if (minPosition == gradient.begin()+2) { grad_sum = abs(grad_135_1 - grad_135_2) + abs(grad_135_1 - grad_135_3) + abs(grad_135_2 - grad_135_3); if (grad_sum > 100) { if (grad_45_2 > 3 * (grad_45_1 + grad_45_3) && grad_135_2 > 3 * (grad_135_1 + grad_135_3)) { if (abs(p3[j + 4] - p0[j + 2]) < abs(p0[j + 2] - p6[j])) { p[j] = p3[j + 4] + (p4[j] + p7[j + 2] - p2[j + 2] - p5[j + 4]) / 2; } else { p[j] = p6[j] - (p4[j] + p7[j + 2] - p2[j + 2] - p5[j + 4]) / 2; } } } else { if (grad_45_2 > 3 * (grad_45_1 + grad_45_3)) { if (abs(p3[j + 4] - p0[j + 2]) < abs(p0[j + 2] - p6[j])) { p[j] = p3[j + 4] + (p4[j] + p7[j + 2] - p2[j + 2] - p5[j + 4]) / 2; } else { p[j] = p6[j] - (p4[j] + p7[j + 2] - p2[j + 2] - p5[j + 4]) / 2; } } } } if (minPosition == gradient.begin()+3) { grad_sum = abs(grad_45_1 - grad_45_2) + abs(grad_45_1 - grad_45_3) + abs(grad_45_2 - grad_45_3); if (grad_sum > 100) { if (grad_135_2 > 3 * (grad_135_1 + grad_135_3) && grad_45_2 > 3 * (grad_45_1 + grad_45_3)) { if (abs(p1[j] - p0[j + 2]) < abs(p0[j + 2] - p8[j + 4])) { p[j] = p1[j] + (p5[j + 4] + p6[j] - p2[j + 2] - p4[j]) / 2; } else { p[j] = p8[j + 4] - (p5[j + 4] + p6[j] - p2[j + 2] - p4[j]) / 2; } } } else { if (grad_135_2 > 3 * (grad_135_1 + grad_135_3)) { if (abs(p1[j] - p0[j + 2]) < abs(p0[j + 2] - p8[j + 4])) { p[j] = p1[j] + (p5[j + 4] + p6[j] - p2[j + 2] - p4[j]) / 2; } else { p[j] = p8[j + 4] - (p5[j + 4] + p6[j] - p2[j + 2] - p4[j]) / 2; } } } }
} } clock_t end = clock(); std::cout << "\r" << "DPC Done! Elapsed " << double(end - begin) / CLOCKS_PER_SEC * 1000 << " ms." << std::endl; }
uchar dpc_thres = 30; dpc(raw, dpc_thres);
|