Попытка создать текстуру для нового набора UV из исходного набора UV и текстуры, но хотелось бы захватить больше текстурC#

Место общения программистов C#
Ответить
Anonymous
 Попытка создать текстуру для нового набора UV из исходного набора UV и текстуры, но хотелось бы захватить больше текстур

Сообщение Anonymous »

Как я уже сказал, у меня есть сетка, на которой я решил переделать UV-развертки, и в целях экономии времени я сохранил исходные UV-развертки по граням, а также новые UV-развертки в отдельных файлах. Код, который у меня есть, успешно переносит и помещает детали из старой текстуры в новую, но из-за того, что пиксели не идеально ложатся на край треугольника, в результате получается много швов.
Изображение

Я бы благодарен, если кто-нибудь поможет, увеличив размер захваченного/помещенного треугольника на пару пикселей, чтобы устранить эти швы:
program.cs:
using System.Drawing;
using Emgu.CV;
using Emgu.CV.CvEnum;
using Emgu.CV.Structure;
using Emgu.CV.Util;

namespace texgen
{
internal class Program
{
static void Main()
{
// Paths to the binary files and images
string originalUVFilePath = @"E:\uvbackup.bin";
string newUVFilePath = @"E:\uvnewbackup.bin";
string originalImagePath = @"E:\Ship_Mat_Fed_Galaxy_2019_Type1_D.bmp";
string newImagePath = @"E:\output_image.bmp";

// Read and normalize the UVW coordinates
UVWCoordinates[] originalUVWs = UVWReader.ReadAndNormalizeUVWCoordinates(originalUVFilePath);
UVWCoordinates[] newUVWs = UVWReader.ReadAndNormalizeUVWCoordinates(newUVFilePath);

// Load the original image
Mat originalImage = CvInvoke.Imread(originalImagePath, ImreadModes.Color);

// Create a new blank image
Mat newImage = new Mat(originalImage.Size, DepthType.Cv8U, 3);
newImage.SetTo(new MCvScalar(0));

// Map the texture
UVWMapper.MapTexture(originalImage, originalUVWs, newUVWs, newImage);

// Save the new image
CvInvoke.Imwrite(newImagePath, newImage);

Console.WriteLine("Processing done. Check the new image.");
}
}
}

UVWReader.cs:
using System.IO;
using System.Collections.Generic;
using System.Numerics;

public struct UVWCoordinates
{
public int FaceIndex;
public Vector3 UVW1;
public Vector3 UVW2;
public Vector3 UVW3;
}

public class UVWReader
{
public static UVWCoordinates[] ReadAndNormalizeUVWCoordinates(string filePath)
{
var coordinatesList = new List();

using (var reader = new BinaryReader(File.Open(filePath, FileMode.Open)))
{
while (reader.BaseStream.Position != reader.BaseStream.Length)
{
var coord = new UVWCoordinates
{
FaceIndex = reader.ReadInt32(),
UVW1 = NormalizeUVW(new Vector3((float)reader.ReadDouble(), (float)reader.ReadDouble(), (float)reader.ReadDouble())),
UVW2 = NormalizeUVW(new Vector3((float)reader.ReadDouble(), (float)reader.ReadDouble(), (float)reader.ReadDouble())),
UVW3 = NormalizeUVW(new Vector3((float)reader.ReadDouble(), (float)reader.ReadDouble(), (float)reader.ReadDouble()))
};

coordinatesList.Add(coord);
}
}

return coordinatesList.ToArray();
}

private static Vector3 NormalizeUVW(Vector3 uvw)
{
return new Vector3(uvw.X - (float)Math.Floor(uvw.X), uvw.Y - (float)Math.Floor(uvw.Y), uvw.Z);
}
}

UVWMapper.cs:
using Emgu.CV.CvEnum;
using Emgu.CV.Structure;
using Emgu.CV.Util;
using System.Numerics;
using System.Drawing;

public class UVWMapper
{
public static void MapTexture(
Mat originalImage,
UVWCoordinates[] originalUVWs,
UVWCoordinates[] newUVWs,
Mat newImage)
{
for (int i = 0; i < originalUVWs.Length; i++)
{
var origUVW = originalUVWs;
var newUVW = newUVWs;

// Define the source points (original UVs)
PointF[] srcPoints = new PointF[]
{
new PointF(origUVW.UVW1.X * originalImage.Width, (1 - origUVW.UVW1.Y) * originalImage.Height),
new PointF(origUVW.UVW2.X * originalImage.Width, (1 - origUVW.UVW2.Y) * originalImage.Height),
new PointF(origUVW.UVW3.X * originalImage.Width, (1 - origUVW.UVW3.Y) * originalImage.Height)
};

// Define the destination points (new UVs)
PointF[] dstPoints = new PointF[]
{
new PointF(newUVW.UVW1.X * newImage.Width, (1 - newUVW.UVW1.Y) * newImage.Height),
new PointF(newUVW.UVW2.X * newImage.Width, (1 - newUVW.UVW2.Y) * newImage.Height),
new PointF(newUVW.UVW3.X * newImage.Width, (1 - newUVW.UVW3.Y) * newImage.Height)
};

// Get the transformation matrix
Mat transformationMatrix = CvInvoke.GetAffineTransform(srcPoints, dstPoints);

// Extract the triangle from the original image
Mat originalTriangle = ExtractTriangle(originalImage, srcPoints);

// Warp the triangle to the new coordinates
Mat warpedTriangle = new Mat();
CvInvoke.WarpAffine(originalTriangle, warpedTriangle, transformationMatrix, newImage.Size, Inter.Linear, Warp.Default, BorderType.Constant, new MCvScalar(0));

// Add the warped triangle to the new image
CvInvoke.Add(newImage, warpedTriangle, newImage);
}
}

private static Mat ExtractTriangle(Mat image, PointF[] srcPoints)
{
// Create a mask for the triangular area
Mat mask = new Mat(image.Size, DepthType.Cv8U, 1);
mask.SetTo(new MCvScalar(0));
VectorOfPoint triangle = new VectorOfPoint(Array.ConvertAll(srcPoints, p => new Point((int)p.X, (int)p.Y)));
CvInvoke.FillConvexPoly(mask, triangle, new MCvScalar(255));

// Extract the triangular portion from the image
Mat triangularPortion = new Mat();
CvInvoke.BitwiseAnd(image, image, triangularPortion, mask);

return triangularPortion;
}
}


Подробнее здесь: https://stackoverflow.com/questions/786 ... -and-textu
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»