diff --git a/libs/MVS/SceneTexture.cpp b/libs/MVS/SceneTexture.cpp index c17d621..a773d28 100644 --- a/libs/MVS/SceneTexture.cpp +++ b/libs/MVS/SceneTexture.cpp @@ -9744,41 +9744,51 @@ bool PointInTriangle(const Point2f& p, const Point2f& a, const Point2f& b, const barycentric.y >= 0 && barycentric.y <= 1 && barycentric.z >= 0 && barycentric.z <= 1); } - // 辅助函数:从图像中双线性插值采样颜色 -// SampleImageBilinear 函数可能存在错误 +// 修正颜色顺序和边界处理 Pixel8U SampleImageBilinear(const Image8U3& image, const Point2f& point) { - float x = point.x, y = point.y; - int x0 = (int)x, y0 = (int)y; - int x1 = x0 + 1, y1 = y0 + 1; + // 边界检查,防止越界 + float x = CLAMP(point.x, 0.0f, (float)(image.cols - 1)); + float y = CLAMP(point.y, 0.0f, (float)(image.rows - 1)); + + int x0 = (int)floor(x); + int y0 = (int)floor(y); + int x1 = std::min(x0 + 1, image.cols - 1); + int y1 = std::min(y0 + 1, image.rows - 1); - // 边界检查 - x1 = MIN(x1, image.cols-1); - y1 = MIN(y1, image.rows-1); + // 确保x0,y0不会超出下界 + x0 = std::max(0, x0); + y0 = std::max(0, y0); float dx = x - x0; float dy = y - y0; + float dx1 = 1.0f - dx; + float dy1 = 1.0f - dy; - // 正确获取像素(注意OpenCV是BGR顺序) + // 获取四个角点的像素 const Pixel8U& p00 = image(y0, x0); const Pixel8U& p01 = image(y0, x1); const Pixel8U& p10 = image(y1, x0); const Pixel8U& p11 = image(y1, x1); - // 双线性插值计算 - Pixel8U result; - for (int c = 0; c < 3; ++c) { - float v00 = p00[c]; - float v01 = p01[c]; - float v10 = p10[c]; - float v11 = p11[c]; - - float top = v00 + (v01 - v00) * dx; - float bottom = v10 + (v11 - v10) * dx; - result[c] = (uint8_t)(top + (bottom - top) * dy); - } + // 方法1:使用结构体成员访问(推荐) + float b = p00.b * dx1 * dy1 + p01.b * dx * dy1 + p10.b * dx1 * dy + p11.b * dx * dy; + float g = p00.g * dx1 * dy1 + p01.g * dx * dy1 + p10.g * dx1 * dy + p11.g * dx * dy; + float r = p00.r * dx1 * dy1 + p01.r * dx * dy1 + p10.r * dx1 * dy + p11.r * dx * dy; - return result; + /* + // 方法2:如果Pixel8U支持[]操作符 + // 注意:OpenMVS的Pixel8U可能是BGR或RGB顺序,需要根据实际情况调整 + float b = p00[0] * dx1 * dy1 + p01[0] * dx * dy1 + p10[0] * dx1 * dy + p11[0] * dx * dy; + float g = p00[1] * dx1 * dy1 + p01[1] * dx * dy1 + p10[1] * dx1 * dy + p11[1] * dx * dy; + float r = p00[2] * dx1 * dy1 + p01[2] * dx * dy1 + p10[2] * dx1 * dy + p11[2] * dx * dy; + */ + + return Pixel8U( + (unsigned char)CLAMP(b, 0.0f, 255.0f), + (unsigned char)CLAMP(g, 0.0f, 255.0f), + (unsigned char)CLAMP(r, 0.0f, 255.0f) + ); } void FillTextureGaps2(Image8U3& textureAtlas, const Mesh::TexCoordArr& faceTexcoords,