OpenCV Java中Matlab interp2函数等效实现及remap参数解析
嘿,我来帮你搞定这个问题!
OpenCV Java 中与 Matlab interp2 等效的实现方案
首先明确:OpenCV 里没有和 interp2 完全一一对应的函数,但**remap 确实是实现你需求的核心工具**——它完全可以达成你Matlab代码里的效果:只对图像宽度做overSample倍的超采样,高度保持不变。
先搞懂 remap 的 map1 和 map2 参数
这俩是用来指定「目标图像每个像素对应原图像坐标」的映射矩阵,说直白点:
map1:单通道浮点矩阵时,存储目标像素对应的原图像x坐标(列方向);也可以是双通道矩阵同时存x和y(这时map2不用传)map2:当map1是单通道时,这个参数是单通道浮点矩阵,存储目标像素对应的原图像y坐标(行方向)
举个例子:目标图像里的像素点(dstY, dstX),它在原图像中对应的位置就是(map2[dstY][dstX], map1[dstY][dstX]),OpenCV会根据你选的插值方法算出这个位置的像素值。
对应你Matlab代码的OpenCV Java实现
你的Matlab代码是对图像宽度做overSample倍插值,高度不变,推测用的是线性或最近邻插值(从'ne...'来看)。下面是一步步的实现:
1. 准备原图像
假设你已经读取了原图像Mat srcImg。
2. 确定目标图像尺寸
int srcWidth = srcImg.cols(); int srcHeight = srcImg.rows(); int overSample = 2; // 这里换成你的超采样倍数 int dstWidth = srcWidth * overSample; int dstHeight = srcHeight; // 高度和原图一致
3. 创建并填充映射矩阵
需要两个和目标图像尺寸一致的单通道浮点Mat:
Mat mapX = new Mat(dstHeight, dstWidth, CvType.CV_32F); Mat mapY = new Mat(dstHeight, dstWidth, CvType.CV_32F); // 填充映射关系 for (int y = 0; y < dstHeight; y++) { for (int x = 0; x < dstWidth; x++) { // 宽度方向线性映射:目标x对应原图像的x(注意OpenCV是0索引,Matlab是1索引) float srcX = (float) (x * (srcWidth - 1.0) / (dstWidth - 1.0)); // 高度方向完全对应,因为没缩放 float srcY = (float) y; mapX.put(y, x, srcX); mapY.put(y, x, srcY); } }
4. 调用remap完成插值
选择对应的插值方法:
Mat dstImg = new Mat(); // 线性插值对应Matlab的'linear',最近邻用INTER_NEAREST Imgproc.remap(srcImg, dstImg, mapX, mapY, Imgproc.INTER_LINEAR, Imgproc.BORDER_CONSTANT, new Scalar(0));
小提示
- 如果你的Matlab代码用的是最近邻插值,把
INTER_LINEAR换成INTER_NEAREST即可 - OpenCV还支持
INTER_CUBIC(三次插值)等更多方法,可根据需求调整
内容的提问来源于stack exchange,提问作者EdyAzar
相关产品推荐
相关产品推荐

