これはかなり単純な要求のように思えますが、問題は少し微妙だと思います。X および Y 派生物の 8 ビット符号なしバージョンが必要なだけです。ソース イメージも 8 ビット符号なしです。
これが私が使用した1つのアプローチです:
cv::Mat dx, dy;
cv::Sobel(img, dx, CV_16S, 1, 0);
cv::Sobel(img, dy, CV_16S, 0, 1);
dx = cv::abs(dx);
dy = cv::abs(dy);
cv::normalize(dx, dx8u, 0x00, 0xFF, cv::NORM_MINMAX, CV_8U);
cv::normalize(dy, dy8u, 0x00, 0xFF, cv::NORM_MINMAX, CV_8U);
私が本当に好きではないのは、normalize
関数の使用です。無駄に思えます。Sobel 演算子を 8 ビット イメージに直接計算しようとすると ( に設定ddepth
して-1
)、すべての負の値を "切り取る" ように見えます。絶対値を計算してから 8 で割ろうとすると (ソーベル演算子の絶対値を [0, 255] に近似的にマッピングするため)、それでも 16 ビットの画像であり、8 ビットに変換する必要があります。またもったいないようです。これを行うより良い方法はありますか?
この質問の重要な側面は、16 ビットの署名付きイメージに対して操作を実行し、その結果を 8 ビット イメージに直接配置する方法だと思います。そうすれば、事後に追加の変換を実行する必要はありません。
アップデート:
最終的な解決策は次のとおりです。
cv::Mat dx, dy;
cv::Sobel(m, dx, CV_16S, 1, 0);
cv::Sobel(m, dy, CV_16S, 0, 1);
cv::convertScaleAbs(dx / 8, dx);
cv::convertScaleAbs(dy / 8, dy);