求C++代码output.at(x,y)=target.at(dx,dy)的OpenCV Java等效实现
解决OpenCV Java像素赋值的偏移问题
嘿,我来帮你搞定这个OpenCV Java的像素赋值问题!你遇到的图像偏移问题,核心原因是没理清C++和Java版OpenCV在坐标、像素数据处理上的细节差异,再加上可能对Mat.at、get()/put()的参数顺序理解有误。
先把关键差异说清楚:
- 在C的OpenCV里,
Mat::at<T>(row, col)的参数顺序是行(对应图像的垂直y轴)在前,列(对应水平x轴)在后。如果你的C代码里output.at(x, y)是故意把x作为行、y作为列,那Java代码要保持同样的参数顺序;但如果是笔误(比如本来应该写at(y, x)),那Java代码也得跟着调整。 - Java中
Mat.get(row, col)和put(row, col, ...)的参数顺序和C++的at完全一致,都是先写行索引,再写列索引。
接下来分两种情况给你正确代码:
情况1:你的C++代码参数顺序是正确的(x是行,y是列)
如果你的C++代码里x确实代表行索引(垂直方向)、y代表列索引(水平方向),那对应的Java代码要注意:get()方法返回的是一个double[]数组(对应像素的各通道值),直接传给put()就可以,但要保证target和output的通道数、数据类型完全一致(比如都是CV_8UC3的彩色图):
// 获取target中(dx, dy)位置的像素值 double[] pixel = target.get(dx, dy); // 将像素值写入output的(x, y)位置 output.put(x, y, pixel);
情况2:你的C++代码参数顺序搞反了(应该是at(y, x))
很多人会搞混OpenCV的坐标逻辑——图像的x是水平方向的列,y是垂直方向的行,所以正确的C++写法应该是output.at(y, x) = target.at(dy, dx);。如果是这种情况,你的Java代码必须调整参数顺序:
double[] pixel = target.get(dy, dx); output.put(y, x, pixel);
为什么你的原代码会出现偏移?
你写的output.put(x, y, target.get(dx, dy))出现偏移,大概率是把x和y的顺序搞反了——比如你误以为x是列、y是行,但实际put()的第一个参数是行(y方向),第二个是列(x方向),这就会导致整个图像的行和列被互换,自然出现严重偏移甚至图像旋转的问题。
额外小提示
- 如果是单通道的灰度图,你可以简化代码,直接取数组的第一个元素:
// 适用于CV_8UC1的单通道灰度图 double pixelVal = target.get(dx, dy)[0]; output.put(x, y, pixelVal); - 一定要确保
dx、dy在target的行、列范围内,x、y在output的行、列范围内,不然会抛出越界异常哦。
内容的提问来源于stack exchange,提问作者Udaib Khan
相关产品推荐
相关产品推荐

