PythonとC++で、同じような実装をしたつもりが結果が異なるので少しハマりました。
# Python import cv2 import numpy as np mat = np.zeros((100, 100), np.uint8) + 100 cv2.rectangle(mat, (20, 20), (80, 80), 128, cv2.FILLED) roi = mat[20:80, 20:80] mat[20:80, 20:80] = cv2.blur(roi, (11, 11))
// C++ cv::Mat mat = cv::Mat1b::zeros(100, 100) + 100; cv::rectangle(mat, cv::Rect(20, 20, 60, 60), cv::Scalar(128), cv::FILLED); cv::Mat roi = mat(cv::Rect(20, 20, 60, 60)); cv::blur(roi, roi, { 11, 11 }); // この時点のmatが、Pythonと異なる
まあこの例だと一目なんですが、実際はもう少し入り組んでいたので最小化するのに苦労しました。roiにだけ処理したいのですが外側の画素値も見ちゃうんですね。それはそうか、という気もするような、しないような。本能的にコピーを避けようとしてしまうのですが、Pythonと同じ結果にしたければ、コピーすれば良いです。
cv::Mat mat = cv::Mat1b::zeros(100, 100) + 100; cv::rectangle(mat, cv::Rect(20, 20, 60, 60), cv::Scalar{128}, cv::FILLED); cv::Mat roi = mat(cv::Rect(20, 20, 60, 60)).clone(); cv::blur(roi, roi, { 11, 11 }); mat(cv::Rect(20, 20, 60, 60)) = roi;
逆にC++の元の実装と同じ挙動をPythonで実現したくなったら、結構面倒そうですね。
ちなみにblurのboderType引数にBORDER_ISOLATEDというものがありますが、これを使っても外側の値は参照されるようです。コメントにはdo not look outside of ROI
と書いてあるんですが、これはまた暇なときにソースを読んでみようかな。