/// <inheritdoc/> protected override bool DoTransferColor(Tensor <float> source, Tensor <float> target, Tensor <float> output) { var(width, height) = (target.Width(), target.Height()); var fY = 1f / height; var fX = 1f / width; Parallel.For(0, height, row => { var sampler = new Sampler <float>(source); var targetData = ((DenseTensor <float>)target).Buffer.Span; var outputData = ((DenseTensor <float>)output).Buffer.Span; var k = row * width * 3; var yPos = fY * row; for (int col = 0; col < width; ++col, k += 3) { var(r, g, b) = sampler[fX * col, yPos]; var(_, u, v) = PixelOps.RgbToYuv(r, g, b); var y = PixelOps.Luma(targetData, k); PixelOps.YuvToRgb(y, u, v, outputData, k); } }); return(true); }
/// <inheritdoc/> protected sealed override bool DoTransferColor(Tensor <float> source, Tensor <float> target, Tensor <float> output) { var sourceMean = PixelOps.Mean(source); var targetMean = PixelOps.Mean(target); var sourceSigma = PixelOps.Covariance(source, sourceMean); var targetSigma = PixelOps.Covariance(target, targetMean); if (GetCoefficients(sourceSigma, targetSigma, out Matrix3 A)) { var b = Vector3.Zero; _ = sourceMean.Sub(A._ * targetMean, ref b); PixelOps.LinearTransfer(A, b, target, output); return(true); } return(false); }