鉴于以下输出:
[11233,11334,11434,10897] [44,44,45,43] [-31,81,-86,-111]
从这段代码
std::cout << mat32sc1;
channels[1] = mat32sc1 / 256;
channels[0] = mat32sc1 - channels[1] * 256;
std::cout << channels[1];
std::cout << channels[0];
Run Code Online (Sandbox Code Playgroud)
我原以为11233/256是43,使用整数除法?
我的假设是冤枉c ++总是通过地板进行整数除法吗?
这是我目前的编码功能.
void encode(cv::Mat & src, cv::Mat & dst)
{
cv::Mat_<int> mat32sc1;
src.convertTo(mat32sc1, CV_32SC1, 10, 11000);
std::vector<cv::Mat> channels;
channels.resize(3);
// bitwise_and(mat32sc1, cv::Scalar(255), channels[0]); // is this needed or will converTo truncate automaticly.
// channels[0].convertTo(channels[0], CV_8UC1);
// mat32sc1.convertTo(channels[1], CV_8UC1, 1.0 / (1 << 8));
channels[2] = cv::Mat::zeros(src.rows, src.cols, CV_8UC1);
int flag = 256;
// std::cout << mat32sc1;
channels[1] = mat32sc1 / flag;
channels[0] = mat32sc1 - channels[1] * flag;
cv::Mat_<int> off = (channels[0] < 0) / 255;
//std::cout << off;
channels[1] -= off;
channels[0] = mat32sc1 - channels[1] * flag;
//std::cout << channels[1];
//std::cout << channels[0];
channels[0].convertTo(channels[0], CV_8UC1);
channels[1].convertTo(channels[1], CV_8UC1);
cv::merge(channels, dst);
}
Run Code Online (Sandbox Code Playgroud)
任何更聪明的方法来获得相同的结果
该除法确实不是整数除法。OpenCV 中的大多数函数将其输入转换为标量,标量是 1、2、3 或 4 个双精度数的容器。OpenCV 中执行类似操作的其他函数(scaleAdd、addWeighted、convertTo 等)也都适用于双精度数。换句话说,您的代码执行双除和结果舍入。这就是为什么你得到 44 而不是 43。
编辑:
至于“编码”功能,您不需要执行复杂的操作。新矩阵的字节已经存在。您只需要创建访问它们的便捷方式:
Mat temp(src.size(), CV_8UC4, src.data);
Run Code Online (Sandbox Code Playgroud)
这将创建指向 src 数据的新矩阵头(即没有数据副本)。但它不会将数据视为具有单通道的整数矩阵,而是将其视为无符号字符的 4 通道矩阵(具有相同的宽度和高度)。您可以使用多通道矩阵执行任何操作:split()、merge()、mixChannels() 等...