c# - 在 c# 中使用 emgucv 旋转图像的像素错误
问题描述
我正在尝试使用带有 GetRotationMatrix2D 和 WarpAffine 的 emgucv 旋转图像。我尝试了不同的方法来旋转图像,虽然这个方法看起来是迄今为止最好的,但它似乎有时会产生错误的像素。
我使用以下方法将图像读入 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);
.....
此代码正常工作,但在某些情况下,图像的某些部分相互重叠,就好像旋转分别应用于图像片段一样。我正在使用 16 位 Tiff 文件。
这是我旋转图像后得到的结果:
解决方案
您是否尝试过使用 RotatedRect 而不是旋转矩阵?当我想将由 RotatedRect 定义的 ROI 从源图像复制到目标图像时,我会使用此技术。它应该适用于任何图像。下面是一个演示此概念的示例 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);
}
}
这个快速示例将剪辑生成的图像。我将作为练习留给读者调整目标大小以防止剪辑。
道格
推荐阅读
- php - laravel 数据库播种器添加随机添加外键 id 到种子
- wordpress - 为什么 Woocommerce Paypal 访客结账不适用于我的客户,但使用 PayPal 帐户付款?
- pagespeed - google pagespeed见解面临的问题
- magento2 - Magento 2.3.3 销售/订单/视图缺少重要信息
- google-chrome - Cannot close all Google Chrome processes on Windows 10 and cannot run the browser
- php - unserialize():偏移量 0 的 1 个字节出错
- android - OkHttp3,改造和证书固定:如何使固定到期
- python - 如何在python中循环字符串或按钮?
- laravel - 注销护照功能需要通过什么
- regex - 使用正则表达式搜索和替换以增加 Visual Studio Code 中的数字