我正在尝试在 C 中使用双线性插值复制 OpenCV 的大小调整算法。我想要实现的是生成的图像与 OpenCV 生成的图像完全相同(像素值)。我对缩小而不是放大特别感兴趣,我有兴趣在单通道灰度图像上使用它。在网上我读到双线性插值算法在缩小和放大之间是不同的,但是我没有找到缩小实现的公式,所以很可能我写的代码是完全错误的。我写的内容来自我在计算机图形学和 OpenGL 的大学课程中获得的插值知识。我编写的算法的结果是图像在视觉上与 OpenCV 生成的图像相同,但其像素值并不完全相同(尤其是靠近边缘)。你能告诉我双线性插值的收缩算法和可能的实现吗?
注意:所附代码是一个一维滤波器,必须先水平应用,然后垂直应用(即转置矩阵)。
Mat rescale(Mat src, float ratio){
float width = src.cols * ratio; //resized width
int i_width = cvRound(width);
float step = (float)src.cols / (float)i_width; //size of new pixels mapped over old image
float center = step / 2; //V1 - center position of new pixel
//float center = step / src.cols; //V2 - other possible center position of new pixel
//float center = 0.099f; //V3 - Lena 512x512 lower difference possible to OpenCV
Mat dst(src.rows, i_width, CV_8UC1);
//cycle through all rows
for(int j = 0; j < src.rows; j++){
//in each row compute new pixels
for(int i = 0; i < i_width; i++){
float pos = (i*step) + center; //position of (the center of) new pixel in old map coordinates
int pred = floor(pos); //predecessor pixel in the original image
int succ = ceil(pos); //successor pixel in the original image
float d_pred = pos - pred; //pred and succ distances from the center of new pixel
float d_succ = succ - pos;
int val_pred = src.at<uchar>(j, pred); //pred and succ values
int val_succ = src.at<uchar>(j, succ);
float val = (val_pred * d_succ) + (val_succ * d_pred); //inverting d_succ and d_pred, supposing "d_succ = 1 - d_pred"...
int i_val = cvRound(val);
if(i_val == 0) //if pos is a perfect int "x.0000", pred and succ are the same pixel
i_val = val_pred;
dst.at<uchar>(j, i) = i_val;
}
}
return dst;
}