Найти изображение в изображении С#

У меня есть отсканированный документ (фактически форма), заполненный рукописной информацией.

У меня есть растровое изображение пустой формы.

как я могу «отменить» печатную форму, чтобы извлечь только почерк.

Я использую С#... Спасибо, Джонатан.


person Community    schedule 11.08.2009    source источник


Ответы (2)


Что вы хотите сделать, так это вычесть изображение пустой формы из изображения формы с рукописным вводом. Это даст вам разумное изображение только почерка.

Обратите внимание, что при этом изображения не будут зарегистрированы. Регистрация выстроит их так, чтобы они находились в одинаковой ориентации, чтобы дать вычитанию наилучшие шансы на успех. Если ваши изображения плохо выровнены, вам придется изучить регистрацию изображений.

Вот фрагмент кода, который я написал некоторое время назад, чтобы сделать что-то подобное (этот код выделен красным цветом):

        Bitmap b1 = new Bitmap(fname1);
        Bitmap b2 = new Bitmap(fname2);

        if (b1.Height != b2.Height || b1.Width != b2.Width) {
           MessageBox.Show("Input files are not the same dimensions!");
           Application.Exit();
        }

        totalPixels = b1.Height * b1.Width * 4;

        Bitmap outImg = new Bitmap(b1.Width, b1.Height, System.Drawing.Imaging.PixelFormat.Format32bppRgb);

        BitmapData b1Data = b1.LockBits(new Rectangle(0, 0, b1.Width, b1.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppRgb);
        BitmapData b2Data = b2.LockBits(new Rectangle(0, 0, b1.Width, b1.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppRgb);
        BitmapData oData = outImg.LockBits(new Rectangle(0, 0, b1.Width, b1.Height), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppRgb);

        byte[] cur1 = new byte[b1Data.Stride * b1Data.Height];
        byte[] cur2 = new byte[b2Data.Stride * b2Data.Height];
        byte[] curOut = new byte[b2Data.Stride * b2Data.Height];

        Marshal.Copy(b1Data.Scan0, cur1, 0, b1Data.Stride * b1Data.Height);
        Marshal.Copy(b2Data.Scan0, cur2, 0, b2Data.Stride * b2Data.Height);

        for (int i = 0; i < b1Data.Stride * b1Data.Height; i += 4) {
           byte temp1 = cur1[i], temp2 = cur2[i], first = 0, second = 0;
           curOut[i] = 0;
           first = (byte) ((temp1 > temp2) ? temp1 - temp2 : temp2 - temp1);

           temp1 = cur1[i + 1];
           temp2 = cur2[i + 1];
           curOut[i + 1] = 0;
           second = (byte) ((temp1 > temp2) ? temp1 - temp2 : temp2 - temp1);

           temp1 = cur1[i + 2];
           temp2 = cur2[i + 2];
           curOut[i + 2] = (byte) ((temp1 > temp2) ? temp1 - temp2 : temp2 - temp1);
           curOut[i + 2] = (byte) ((first + second + curOut[i + 2]) * 255);

           curPixel = i;
        }

        Marshal.Copy(curOut, 0, oData.Scan0, b2Data.Stride * b2Data.Height);

        b1.UnlockBits(b1Data);
        b2.UnlockBits(b2Data);
        outImg.UnlockBits(oData);

        outImg.Save(outfile);
person Ron Warholic    schedule 11.08.2009
comment
Да, смотрите мое редактирование относительно регистрации. Если у вас есть изображения, которые очень близки, регистрация может быть такой же простой, как применение небольшого поворота или изменение гистограммы. Если они находятся дальше друг от друга, вам нужно будет спроецировать их на однородное пространство для сравнения. - person Ron Warholic; 12.08.2009
comment
Сид. Что такое регистрация изображения? Можете ли вы указать мне некоторую информацию об этом. Пробовали ли вы также применить распознавание к тексту? Спасибо! - person ; 12.08.2009
comment
Распознавание рукописного ввода — это совсем другая проблема, чем простое извлечение информации из изображения. Я предлагаю вам изучить стороннее решение, которое сделает это за вас, поскольку существуют коммерческие решения, которые по-прежнему не очень хорошо справляются со своей задачей. Что касается регистрации изображений, статья в Википедии является отличным началом en.wikipedia.org/wiki/Image_registration. - person Ron Warholic; 12.08.2009
comment
О да, у меня есть сторонние инструменты для этого. спасибо за идеи, код и ссылку. - person ; 12.08.2009
comment
Если данные, введенные в поля, перекрывают сами поля (т. е. рукописный текст за пределами полей), вычитание пустых форм также сотрет перекрывающиеся области. - person Eric J.; 12.08.2009

В качестве альтернативы (и, возможно, гораздо более быстрого метода) не могли бы вы просто сохранить позиции прямоугольника, где будут «поля», а затем просто извлечь пиксели для каждого прямоугольника?

Темная ночь

person Darknight    schedule 11.08.2009
comment
это может быть хорошим решением, но люди редко пишут в правильном месте - person ; 12.08.2009
comment
Может работать, если отсканированные документы всегда выровнены одинаково. Баллы за простоту. +1 - person Charlie Salts; 12.08.2009
comment
Также хороший метод, может быть проще выровнять области прямоугольника с областями поля, чем выровнять всю форму. Простые эвристики могли устранить фрагменты на краю прямоугольника и, возможно, расширить его, если текст считался «обрезанным». - person Ron Warholic; 12.08.2009