纯c++多线程加持,图像处理速度快而稳定,支持定制,有意vx Bocheng3
效果预览
原图
倾斜校正后
边缘修复后
部分代码:
/**
* @brief 计算四边边缘直线的斜率
* @gray 输入黑白二值图
* @return 斜率
*/
double slopeOfLine(Mat gray) {
vector<vector<double>> lineX(4, vector<double>());//上右下左
vector<vector<double>> lineY(4, vector<double>());
int edgeDistance = 30;// 80;
int rows = gray.rows - 1;
int cols = gray.cols - 1;
int colThresh = cols / 5;
int rowThresh = rows / 5;
int intervalNum = 10;//间隔数
for (int col = colThresh; col < cols - colThresh; col += intervalNum) {//上
for (int row = edgeDistance; row < rows / 5; ++row) {
if (int(gray.at<uchar>(row, col)) != 0) {
int y = 0 - row;
if(lineY[0].size() > 0 && static_cast<int>(y) == static_cast<int>(lineY[0].back())) continue;
lineX[0].push_back(col);
lineY[0].push_back(0 - row);
break;
}
}
}
vector<vector<double>> lineInfo(4, vector<double>());
LineFitLeastSquares(lineX[0], lineY[0], lineInfo[0]);
for (int row = rowThresh; row < rows - rowThresh; row += intervalNum) {//右边
for (int col = cols - edgeDistance; col > cols / 5; --col) {
if (int(gray.at<uchar>(row, col)) != 0) {
if(lineX[1].size() > 0 && col == static_cast<int>(lineX[1].back())) continue;
lineX[1].push_back(col);
lineY[1].push_back(0 - row);
break;
}
}
}
LineFitLeastSquares(lineX[1], lineY[1], lineInfo[1]);
for (int col = colThresh; col < cols - colThresh; col += intervalNum) {//下边
for (int row = rows - edgeDistance; row > rows / 5; --row) {
if (int(gray.at<uchar>(row, col)) != 0) {
int y = 0 - row;
if (lineY[2].size() > 0 && static_cast<int>(y) == static_cast<int>(lineY[2].back())) continue;
lineX[2].push_back(col);
lineY[2].push_back(0-row);
break;
}
}
}
LineFitLeastSquares(lineX[2], lineY[2], lineInfo[2]);
for (int row = rowThresh; row < rows - rowThresh; row += intervalNum) {//左边
for (int col = edgeDistance; col < cols / 5; ++col) {
if (int(gray.at<uchar>(row, col)) != 0) {
if (lineX[3].size() > 0 && col == static_cast<int>(lineX[3].back())) continue;
lineX[3].push_back(col);
lineY[3].push_back(0 - row);
break;
}
}
}
LineFitLeastSquares(lineX[3], lineY[3], lineInfo[3]);
double degree = 0;
int meaningfulNum = 0;//有效个数
for (int i = 0; i < 4; ++i) {
if (lineInfo[i][2] < 0.7 || abs(lineInfo[i][1]) < 5) {//忽略无效数据
continue;
}
if (!_finite(lineInfo[i][2])) {// 是否为有限数 当为NAN、+INF、-INF时,返回0;其他情况返回1
continue;
}
double tmp = slope2degree(lineInfo[i][0]);
if (tmp > 45) tmp -= 90;
else if (tmp < -45) tmp += 90;
degree += tmp;
meaningfulNum++;
}
if (meaningfulNum > 0) {
degree /= meaningfulNum;
//cout << "有效角度:" << degree << endl;
degree = 0 - degree;
}
if (abs(degree) < 0.55) {
degree = 0;
}
return degree;
}