|
|
|
|
@ -9744,41 +9744,51 @@ bool PointInTriangle(const Point2f& p, const Point2f& a, const Point2f& b, const
@@ -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)); |
|
|
|
|
|
|
|
|
|
// 边界检查
|
|
|
|
|
x1 = MIN(x1, image.cols-1); |
|
|
|
|
y1 = MIN(y1, 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); |
|
|
|
|
|
|
|
|
|
// 确保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]; |
|
|
|
|
// 方法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; |
|
|
|
|
|
|
|
|
|
float top = v00 + (v01 - v00) * dx; |
|
|
|
|
float bottom = v10 + (v11 - v10) * dx; |
|
|
|
|
result[c] = (uint8_t)(top + (bottom - top) * dy); |
|
|
|
|
} |
|
|
|
|
/*
|
|
|
|
|
// 方法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 result; |
|
|
|
|
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, |
|
|
|
|
|