我正在尝试在 android studio 中使用 C++ 实现 sobel 边缘检测,并提供最少的库帮助。我必须自己编写算法,所以我不能使用 sobel 或 OpenCV 提供的任何函数。
问题是给定的输出看起来像这个 输出图像一样抽象。我找不到任何相关的讨论。
我正在使用 4 通道 8UC4 垫,JNI 调用 c++。和包含图像的结构,此处描述为stackoverflow.com/questions/24319406/
任何帮助,将不胜感激。非常感谢。
这是代码片段:
#pragma pack(push, 2)
struct RGB {
uchar red;
uchar green;
uchar blue;
float alfa;
};
上面的代码显示了结构
extern "C"
JNIEXPORT void JNICALL
Java_com_example_rakad_skripsi_1c_1realtime_RealTimeDetection_gscale(JNIEnv *env, jobject, jlong frame){
Mat& Frame = *(Mat*)frame;
int row = Frame.rows;
int col = Frame.cols;
GaussianBlur( Frame, Frame, Size( 7, 7), 0, 0 ); // Optional Noise Reduction
for (int y = 0; y < row; y++) {
for (int x = 0; x < col; x++) {
//GET PIXEL VALUE
RGB& frm = Frame.ptr<RGB>(y)[x];
uchar gray = (frm.blue * 0.587) + (frm.green * 0.114) + (frm.red * 0.299); //Grayscale
//REPLACE PIXEL VALUE
frm.red = gray;
frm.blue = gray;
frm.green = gray;
}
}
}
上面的代码是灰度方法。这种方法在 20+ fps 的实时速度下运行良好,没有任何问题。
extern "C"
JNIEXPORT void JNICALL
Java_com_example_rakad_skripsi_1c_1realtime_RealTimeDetection_sobel(JNIEnv *env, jobject, jlong frame){
Mat& Frame = *(Mat*)frame;
int row = Frame.rows;
int col = Frame.cols;
/*SOBEL OPERATOR MATRIX
Gx = [ -1 0 1 ] Gy = [ 1 2 1 ]
[ -2 0 2 ] [ 0 0 0 ]
[ -1 0 1 ] [ -1 -2 -1 ]
*/
/*IMAGE MATRIX
Image = [ 1 2 3 ]
[ 4 5 6 ]
[ 7 8 9 ]
*/
for (int x = 0; x < row; x++) {
for (int y = 0; y < col; y++) {
int gradX, gradY, grad = 0;
RGB& mid = Frame.ptr<RGB>(x)[y];
if (x == 0 || x == row-1 || y == 0 || y == col-1){
gradX = gradY = 0;
} else {
RGB& px1 = Frame.ptr<RGB>(x-1)[y-1]; RGB& px2 = Frame.ptr<RGB>(x)[y-1]; RGB& px3 = Frame.ptr<RGB>(x+1)[y-1];
RGB& px4 = Frame.ptr<RGB>(x-1)[y]; RGB& px6 = Frame.ptr<RGB>(x+1)[y];
RGB& px7 = Frame.ptr<RGB>(x-1)[y+1]; RGB& px8 = Frame.ptr<RGB>(x)[y+1]; RGB& px9 = Frame.ptr<RGB>(x+1)[y+1];
gradX = (px1.red * (-1)) + (px4.red * (-2)) + (px7.red * (-1)) + (px3.red) + (px6.red * 2) + (px9.red);
gradY = (px7.red * (-1)) + (px8.red * (-2)) + (px9.red * (-1)) + (px1.red) + (px2.red * 2) + (px3.red);
}
grad = sqrt((gradX*gradX) + (gradY*gradY));
saturate_cast<uchar>(grad);
mid.red = grad;
mid.green = grad;
mid.blue = grad;
}
}
}
上面的代码很麻烦。它显示了前面提到的图片。