我想从深度图计算渐变角度,并将其分组为某些方向(8个扇区) 但我的功能只计算前3个方向
cv::Mat calcAngles(cv::Mat dimg)//dimg is depth map
{
const int directions_num = 8;//number of directions
const int degree_grade = 360;
int range_coeff = 255 / (directions_num + 1);//just for visualize
cv::Mat x_edge, y_edge, full_edge, angles;
dimg.copyTo(x_edge);
dimg.copyTo(y_edge);
dimg.copyTo(full_edge);
//compute gradients
Sobel( dimg, x_edge, CV_8U, 1, 0, 5, 1, 19, 4 );
Sobel( dimg, y_edge, CV_8U, 0, 1, 5, 1, 19, 4 );
Sobel( dimg, full_edge, CV_8U, 1, 1, 5, 1, 19, 4 );
float freq[directions_num + 1];//for collect direction's frequency
memset(freq, 0, sizeof(freq));
angles = cv::Mat::zeros(dimg.rows, dimg.cols, CV_8U);//store directions here
for(int i = 0; i < angles.rows; i++)
{
for(int j = 0; j < angles.cols; j++)
{
angles.at<uchar>(i, j) = (((int)cv::fastAtan2(y_edge.at<uchar>(i, j), x_edge.at<uchar>(i, j))) / (degree_grade/directions_num) + 1
) * (dimg.at<uchar>(i, j) ? 1 : 0);//fastatan returns values from 0 to 360, if i not mistaken. I want group angles by directions_num sectors. I use first 'direction' (zero value) for zero values from depth map (zero value at my depth map suggest that it is bad pixel)
freq[angles.at<uchar>(i, j)] += 1;
}
}
for(int i = 0; i < directions_num + 1; i++)
{
printf("%2.2f\t", freq[i]);
}
printf("\n");
angles *= range_coeff;//for visualization
return angles;
}
从其中一个框架出来:
47359.00 15018.00 8199.00 6224.00 0.00 0.00 0.00 0.00 0.00
(第一个值是“零像素”,下一个是n位的梯度数,但只有3个不是零)
可视化
有出路吗?或者这些结果还可以吗? PS对不起我的写作错误。英语不是我的母语。
答案 0 :(得分:4)
您使用CV_8U
类型输出Sobel
。它是无符号整数8位。所以它只能存储正值。这就是fastAtan2
返回小于或等于90的原因。将类型更改为CV_16S
并使用short
类型来访问元素:
cv::Sobel(dimg, x_edge, CV_16S, 1, 0, 5, 1, 19, 4);
cv::Sobel(dimg, y_edge, CV_16S, 0, 1, 5, 1, 19, 4);
cv::fastAtan2(y_edge.at<short>(i, j), x_edge.at<short>(i, j))