[英]Pixel errors rotating image with emgucv in c#
I am trying to rotate an image using emgucv with GetRotationMatrix2D and WarpAffine. 我正在尝试使用带有GetRotationMatrix2D和WarpAffine的emgucv旋转图像。 I have tried different methods to rotate the image and while this one seems the best so far, it seems to sometime produce wrong pixels. 我已经尝试了不同的旋转图像的方法,虽然这个方法到目前为止似乎是最好的,但似乎有时会产生错误的像素。
I used the following methods to read an image into a Mat object and rotate it. 我使用以下方法将图像读入Mat对象并旋转它。
public static void LoadImage(string filepath, Mat target, ImreadModes mode = ImreadModes.Grayscale | ImreadModes.AnyDepth)
{
using (var mat = CvInvoke.Imread(filepath, mode))
{
if (mat == null || mat.Size == System.Drawing.Size.Empty)
throw new System.IO.IOException($"Image file '{filepath}' is not readable.");
mat.CopyTo(target);
}
}
void rotateMat(ref Mat src, double angle)
{
Mat r = new Mat();
PointF pc = new PointF((float)(src.Cols / 2.0), (float)(src.Rows / 2.0));
CvInvoke.GetRotationMatrix2D(pc, angle, 1.0, r);
CvInvoke.WarpAffine(src, src, r, src.Size);
}
.....
Mat image = new Mat();
LoadImage("./test.tif", image);
rotateMat(ref image, frameRotation);
.....
This code works without errors, but in some cases parts of the image overlap with each other, as if the rotation was applied to image segments separately. 此代码可以正常工作,但在某些情况下,图像的某些部分会相互重叠,就好像旋转分别应用于图像片段一样。 I am working with 16-bit Tiff files. 我正在使用16位Tiff文件。
Here is the result I obtain after rotating the image: 这是旋转图像后得到的结果:
https://i.stack.imgur.com/xiHvk.jpg https://i.stack.imgur.com/xiHvk.jpg
Instead of a Rotation Matrix have you tried using a RotatedRect instead? 您是否尝试使用RotatedRect而不是旋转矩阵? I use this technique when I want to copy a ROI defined by a RotatedRect from a source image to a destination image. 当我想将RotatedRect定义的ROI从源图像复制到目标图像时,我使用此技术。 It should work for any image. 它适用于任何图像。 Here is an example Windows Console program that demonstrates this concept: 以下是演示此概念的示例Windows控制台程序:
private static void Main(string[] args)
{
Mat source = new Mat("dog.jpg", ImreadModes.Unchanged);
PointF center = new PointF(Convert.ToSingle(source.Width) / 2, Convert.ToSingle(source.Height) / 2);
Mat destination = new Mat(new System.Drawing.Size(source.Width, source.Height), DepthType.Cv8U, 3);
RotatedRect destRect = new RotatedRect(center, source.Size, 35);
Rectangle bbox = destRect.MinAreaRect();
RotateImage(ref source, ref destination, destRect);
CvInvoke.Imshow("Source", source);
CvInvoke.Imshow("Destination", destination);
CvInvoke.WaitKey(0);
}
private static void RotateImage(ref Mat src, ref Mat destination, RotatedRect destRect)
{
PointF[] destCorners = destRect.GetVertices();
PointF[] srcCorners = new PointF[] {
new PointF(0F, src.Height),
new PointF(0F, 0F),
new PointF(src.Width, 0F),
new PointF(src.Width, src.Height)
};
using (Mat aft = CvInvoke.GetAffineTransform(srcCorners, destCorners))
using (Mat warpResult = new Mat(src.Size, src.Depth, src.NumberOfChannels))
{
CvInvoke.WarpAffine(src, warpResult, aft, destination.Size);
warpResult.CopyTo(destination);
}
}
This quickie example will clip the resulting image. 此快速示例将剪切生成的图像。 I will leave as an exercise for the reader to resize the destination to prevent clipping. 我将留下作为练习让读者调整目的地以防止剪裁。
Doug 道格
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.