#c# #opencv #emgucv
#c# #opencv #emgucv
Вопрос:
Я только начал проект распознавания текста несколько недель назад. Я застрял с проблемой искажения изображения, я перепробовал много разных методов, кажется, ничего не работает, так что, пожалуйста, помогите 🙂
Искаженное изображение приведено ниже
Я хочу, чтобы окончательное изображение было таким, как указано ниже
Я уже пытался изменить изображение, но не смог получить окончательное изображение.
public Image<Gray, byte> ImageDeskewOuter(Image<Gray, byte> img)
{
img = img.Resize(img.Height, img.Width, Inter.Linear);
Image<Gray, byte> tmp = new Image<Gray, byte>(img.Bitmap);
tmp = tmp.ThresholdToZero(new Gray(180));
int nZero = tmp.CountNonzero()[0] == 0 ? 1 : tmp.CountNonzero()[0];
if (tmp.Bytes.Length / nZero < 10)
img = tmp.Not();
else
img = img.ThresholdToZero(new Gray(80)).InRange(new Gray(0), new Gray(60)).Not();
tmp = new Image<Gray, byte>(img.Bitmap).Canny(50, 150);
List<Rectangle> rlist = new List<Rectangle>();
Rectangle min = new Rectangle();
Rectangle max = new Rectangle();
VectorOfVectorOfPoint contour = new VectorOfVectorOfPoint();
Mat hier = new Mat();
CvInvoke.FindContours(tmp, contour, hier, RetrType.External, ChainApproxMethod.ChainApproxSimple);
if (contour.Size > 0)
{
for (int i = 0; i < contour.Size; i )
{
Rectangle rec = CvInvoke.BoundingRectangle(contour[i]);
if (rec.Width > 30 amp;amp; rec.Width < 120 amp;amp; rec.Height > 50 amp;amp; rec.Height < 120)
{
rlist.Add(rec);
}
}
min = rlist.OrderBy(x => x.X).FirstOrDefault();
max = rlist.OrderByDescending(x => x.X).FirstOrDefault();
Rectangle roi = Rectangle.Union(min, max);
img.ROI = roi;
}
if (rlist.Count > 0)
{
double angle = LineAngle(min.X, min.Bottom, max.X, max.Bottom, min.X, min.Bottom, max.X, min.Bottom) 3;
img = img.Rotate(angle, new Gray(255), false);
}
return img;
}
Окончательное изображение с использованием вышеуказанной функции
Комментарии:
1. #Gimby, как я объяснил выше, что я хочу изменить изображение, пожалуйста, сосредоточьтесь на этом, не переходите на следующий шаг и не выполняйте распознавание … 🙂
2. Какие библиотеки вы используете?
3. EmguCV.3.1.0.1 с помощью tesseract
Ответ №1:
Шаг 1> Выберите нужный контур и примените CvInvoke.Minarearrect() и скопируйте область изображения в новое изображение
Шаг 2> Создайте растровое изображение, ширина которого равна сумме всей ширины обрезанного изображения (если вы хотите поместить каждое изображение рядом)
Шаг 3> Использование графики для рисования изображения на растровом изображении
public Image<Gray, byte> ImageDeskew(Image<Gray, byte> img)
{
img = img.Resize(img.Height, img.Width, Inter.Linear);
Image<Gray, byte> tmp = new Image<Gray, byte>(img.Bitmap);
tmp = new Image<Gray, byte>(AdjustContrast(tmp.Bitmap, 70));
img = tmp.Not().ThresholdAdaptive(new Gray(255), AdaptiveThresholdType.MeanC, ThresholdType.Binary, 45, new Gray(10));
tmp = new Image<Gray, byte>(img.Bitmap).Canny(50, 150);
List<Image<Gray, byte>> imglist = new List<Image<Gray, byte>>();
Rectangle min = new Rectangle();
Rectangle max = new Rectangle();
VectorOfVectorOfPoint contour = new VectorOfVectorOfPoint();
Mat hier = new Mat();
CvInvoke.FindContours(tmp, contour, hier, RetrType.External, ChainApproxMethod.ChainApproxSimple);
if (contour.Size > 0)
{
for (int i = 0; i < contour.Size; i )
{
RotatedRect rRect = CvInvoke.MinAreaRect(contour[i]);
float area = rRect.Size.Width * rRect.Size.Height;
if (area > (img.Bytes.Length / 10))
{
rlist.Add(rec);
if (rRect.Angle > -45) imglist.Add(img.Copy(rRect));
else imglist.Add(img.Copy(rRect).Rotate(-90, new Gray(255), false));
}
}
}
if (imglist.Count > 0)
{
int xPx = imglist.Sum(x => x.Width);
Bitmap bitmap = new Bitmap(xPx, img.Height);
using (Graphics g = Graphics.FromImage(bitmap))
{
xPx = 0;
imglist.Reverse();
foreach (Image<Gray, byte> i in imglist)
{
g.DrawImage(i.Not().Bitmap, xPx, 0);
xPx = i.Width;
}
}
img = new Image<Gray, byte>(bitmap).Not();
}
return img;
}