openCV:使用重载运算符和不使用重载运算符进行矩阵乘法时的结果不同
openCV: different results when matrix-multiplication with overloaded operator and without
我在 openCV 中有一个这样的矩阵:cv::Mat matrix = cv::Mat::zeros(5, 5, CV_32FC3);
然后,我想以两种不同的方式进行矩阵乘法,第一种是通道方式,第二种是重载运算符。
// VERSION 1:
for (int row_count = 0; row_count < image.rows; row_count++)
{
for (int col_count = 0; col_count < image.cols; col_count++)
{
for (int channel_count = 0; channel_count < 3; channel_count++)
{
matrix.at<cv::Vec3b>(row_count, col_count)[channel_count] = some_image.at<cv::Vec3b>(row_count, col_count)[channel_count] * other_image.at<float>(row_count, col_count);
}
}
}
// VERSION 2:
for (int row_count = 0; row_count < image.rows; row_count++)
{
for (int col_count = 0; col_count < image.cols; col_count++)
{
matrix.at<cv::Vec3b>(row_count, col_count) = some_image.at<cv::Vec3b>(row_count, col_count) * other_image.at<float>(row_count, col_count);
}
}
为什么我在这里得到不同的结果?
编辑:(这里是一个例子,thx@Frank)
int main() {
cv::Vec3b data(127, 81, 24);
float ratio = 0.25f;
cv::Vec3b manual;
manual[0] = data[0] * ratio;
manual[1] = data[1] * ratio;
manual[2] = data[2] * ratio;
cv::Vec3b overloaded = data * ratio;
std::cout << manual << " vs " << overloaded << "\n";
}
输出:
[31, 20, 6] vs [32, 20, 6]
当涉及整数类型时,OpenCV 几乎无处不在地使用 cv::saturate_cast<>
。您 认为 这应该只会改变上溢和下溢的行为方式,但它也会影响浮点值的强制转换方式。
如果想二进制兼容opencv内部代码,手动做涉及整数标量的运算时需要撒一堆cv::saturate_cast<>
int main() {
cv::Vec3b data(127, 81, 24);
float ratio = 0.25f;
cv::Vec3b manual;
manual[0] = cv::saturate_cast<uint8_t>(data[0] * ratio);
manual[1] = cv::saturate_cast<uint8_t>(data[1] * ratio);
manual[2] = cv::saturate_cast<uint8_t>(data[2] * ratio);
cv::Vec3b overloaded = data * ratio;
std::cout << manual << " vs " << overloaded << "\n";
}
这会产生:[32, 20, 6] vs [32, 20, 6]
如预期。
详细信息:,根据文档:
https://docs.opencv.org/4.5.2/db/de0/group__core__utils.html#gab93126370b85fda2c8bfaf8c811faeaf
It perform an efficient and accurate conversion from one primitive type to another.
saturate_cast
这个名字有点误导,因为它不仅使值饱和,而且还努力使转换尽可能准确。把它想象成 quantize_cast<>
而不是。
原始 C++ 行为是将浮点值 舍入为零 将它们转换为整数时,这正是您在计数时想要的。另一方面,cv::saturate_cast<>
将它们四舍五入到 最近的 整数。这在处理量化时在数值上更准确,这就是 OpenCV 在大多数情况下使用整数的方式。
我在 openCV 中有一个这样的矩阵:cv::Mat matrix = cv::Mat::zeros(5, 5, CV_32FC3);
然后,我想以两种不同的方式进行矩阵乘法,第一种是通道方式,第二种是重载运算符。
// VERSION 1:
for (int row_count = 0; row_count < image.rows; row_count++)
{
for (int col_count = 0; col_count < image.cols; col_count++)
{
for (int channel_count = 0; channel_count < 3; channel_count++)
{
matrix.at<cv::Vec3b>(row_count, col_count)[channel_count] = some_image.at<cv::Vec3b>(row_count, col_count)[channel_count] * other_image.at<float>(row_count, col_count);
}
}
}
// VERSION 2:
for (int row_count = 0; row_count < image.rows; row_count++)
{
for (int col_count = 0; col_count < image.cols; col_count++)
{
matrix.at<cv::Vec3b>(row_count, col_count) = some_image.at<cv::Vec3b>(row_count, col_count) * other_image.at<float>(row_count, col_count);
}
}
为什么我在这里得到不同的结果?
编辑:(这里是一个例子,thx@Frank)
int main() {
cv::Vec3b data(127, 81, 24);
float ratio = 0.25f;
cv::Vec3b manual;
manual[0] = data[0] * ratio;
manual[1] = data[1] * ratio;
manual[2] = data[2] * ratio;
cv::Vec3b overloaded = data * ratio;
std::cout << manual << " vs " << overloaded << "\n";
}
输出:
[31, 20, 6] vs [32, 20, 6]
当涉及整数类型时,OpenCV 几乎无处不在地使用 cv::saturate_cast<>
。您 认为 这应该只会改变上溢和下溢的行为方式,但它也会影响浮点值的强制转换方式。
如果想二进制兼容opencv内部代码,手动做涉及整数标量的运算时需要撒一堆cv::saturate_cast<>
int main() {
cv::Vec3b data(127, 81, 24);
float ratio = 0.25f;
cv::Vec3b manual;
manual[0] = cv::saturate_cast<uint8_t>(data[0] * ratio);
manual[1] = cv::saturate_cast<uint8_t>(data[1] * ratio);
manual[2] = cv::saturate_cast<uint8_t>(data[2] * ratio);
cv::Vec3b overloaded = data * ratio;
std::cout << manual << " vs " << overloaded << "\n";
}
这会产生:[32, 20, 6] vs [32, 20, 6]
如预期。
详细信息:,根据文档: https://docs.opencv.org/4.5.2/db/de0/group__core__utils.html#gab93126370b85fda2c8bfaf8c811faeaf
It perform an efficient and accurate conversion from one primitive type to another.
saturate_cast
这个名字有点误导,因为它不仅使值饱和,而且还努力使转换尽可能准确。把它想象成 quantize_cast<>
而不是。
原始 C++ 行为是将浮点值 舍入为零 将它们转换为整数时,这正是您在计数时想要的。另一方面,cv::saturate_cast<>
将它们四舍五入到 最近的 整数。这在处理量化时在数值上更准确,这就是 OpenCV 在大多数情况下使用整数的方式。