我有一个使用OpenCV抖动的任务。我理解这个方法,并用C++编写了它,但是我发现了我不能理解的关于括号的地方。
当我执行这段代码时:
#include<opencv2/opencv.hpp>
#include<highgui.hpp>
#include<iostream>
#include<opencv2/cvconfig.h>
using namespace cv;
using namespace std;
int main() {
Mat img = imread("lena.jpg", IMREAD_COLOR);
Mat bgr[3];
Mat dithering[3];
int x = img.rows;
int y = img.cols;
Mat merger;
Mat temp(x, y, CV_64FC1, Scalar(0));
double e;
split(img, bgr);
for (int l = 0; l < 3; l++) {
bgr[l].convertTo(temp, CV_64FC1);
for (int i = 0; i < x - 1; i++) {
for (int j = 1; j < y - 1; j++) {
if (temp.at<double>(i, j) > 127)
e = temp.at<double>(i, j) - 255;
else
e = temp.at<double>(i, j);
temp.at<double>(i, j + 1) = temp.at<double>(i, j + 1) + e * (7 / 16);
temp.at<double>(i + 1, j - 1) = temp.at<double>(i + 1, j - 1) + e * (3 / 16);
temp.at<double>(i + 1, j) = temp.at<double>(i + 1, j) + e * (5 / 16);
temp.at<double>(i + 1, j + 1) = temp.at<double>(i + 1, j + 1) + e * (1 / 16);
}
}
dithering[l] = Mat(x, y, CV_8UC1, Scalar(0));
for (int i = 0; i < x; i++) {
for (int j = 0; j < y; j++) {
if (temp.at<double>(i, j) > 127)
dithering[l].at<uchar>(i, j) = 255;
else
dithering[l].at<uchar>(i, j) = 0;
}
}
}
merge(dithering,3, merger);
imwrite("dithered.jpg", merger);
namedWindow("original", WINDOW_AUTOSIZE);
namedWindow("dithered", WINDOW_AUTOSIZE);
imshow("original", img);
imshow("dithered", merger);
waitKey(0);
}我有这些结果

这些都是非常糟糕的结果。
但当我删除计算中的括号时:
temp.at<double>(i, j + 1) = temp.at<double>(i, j + 1) + e * 7 / 16;
temp.at<double>(i + 1, j - 1) = temp.at<double>(i + 1, j - 1) + e * 3 / 16;
temp.at<double>(i + 1, j) = temp.at<double>(i + 1, j) + e * 5 / 16;
temp.at<double>(i + 1, j + 1) = temp.at<double>(i + 1, j + 1) + e * 1 / 16;我得到了正确的结果:

我找不到它们之间的区别,但它们带来了不同的结果。
有人能给我解释一下吗?
发布于 2020-04-18 16:42:28
在此表达式中
e * (7 / 16)括号中的子表达式使用整数算术进行求值。也就是说,7 / 16的结果等于0。所以完整的表达式也等于0。
不带括号的表达式
e * 7 / 16评估结果如下:
( e * 7 ) / 16这里使用了带浮点数的算术(变量e被声明为具有double类型),因为int类型的对象被隐式地转换为double类型,这是由于通常的算术转换来确定表达式的公共类型。
https://stackoverflow.com/questions/61286349
复制相似问题