2
$\begingroup$

Suppose I have a image mark

mark=Uncompress[FromCharacterCode[
  Flatten[ImageData[Import["http://i.stack.imgur.com/O0A6a.png"],"Byte"]]]]

Mathematica graphics

And image empty

empty=Uncompress[FromCharacterCode[
  Flatten[ImageData[Import["http://i.stack.imgur.com/fYqMl.png"],"Byte"]]]]

Mathematica graphics

As you see,they are aligned well

HighlightImage[mark, ColorNegate[Binarize[mark]]]

Mathematica graphics

I want to get a result like

{{d,b,c,b,c},{c,d},{c,b,d}}

And a list {{1,2,3,4,5},{8,9},{15,16,17}}


This is current try

bin = ColorNegate[Binarize[empty]] // FillingTransform;
rects = Values[
   ComponentMeasurements[Dilation[bin, 1] // FillingTransform, 
    "BoundingBox"]];
module = Binarize[
  Show[bin, 
   Graphics[{EdgeForm[White], FaceForm[White], Rectangle @@@ rects}]]]

Mathematica graphics

markBin = 
  DeleteSmallComponents[
   ImageSubtract @@ (Binarize[ColorNegate[#]] & /@ {mark, empty})];
rects = Values[
   ComponentMeasurements[Dilation[markBin, 1] // FillingTransform, 
    "BoundingBox"]];
markResult = 
 Binarize[Show[markBin, 
   Graphics[{EdgeForm[White], FaceForm[White], Rectangle @@@ rects}]]]

Mathematica graphics

Mark the result

HighlightImage[module,Values[ComponentMeasurements[markResult, "Centroid"]]]

Mathematica graphics

  1. But I don't know how to get that expectation list.
  2. When the empy and mark is following layout,I have no solution to judge its orientation.

empty

enter image description here

mark

enter image description here

$\endgroup$
4
$\begingroup$

So here's an adaption to this answer of mine where I did some of this splitting work.

First we'll define some stuff to split pixel columns:

splitPixelBlocks[data_, blockSize : _?IntegerQ : 50] :=

  Block[{block = False, counts = 0, countmax = blockSize},
   SplitBy[data,
    (If[Length@Counts[#] > 1, block = True;
       counts = 0;, counts++;
       block = (block && counts <= countmax)];
      block) &]
   ];
deleteConstantBlocks[data_] :=
  DeleteCases[data, {{(pixel_) ..} ..}];
splitColumnBlocks[img_?ImageQ, blockSize : _?IntegerQ : 50] :=

  deleteConstantBlocks@
    splitPixelBlocks[Transpose@ImageData[img], blockSize] // 
   Map[Image@*Transpose@*ImageData@*ImageCrop@*Image];
prepImg[img_?ImageQ] :=
  ImageClip[img, {0, .9}, {0, 1}];

Then we split those:

cols = splitColumnBlocks[
  img = prepImg@
    Uncompress[
     FromCharacterCode[
      Flatten[ImageData[Import["http://i.stack.imgur.com/O0A6a.png"], 
        "Byte"]]]]
  ]

columns

Then split the rows in the columns:

splitRowBlocks[img_?ImageQ, blockSize : _?IntegerQ : 5] :=

 Image /@ deleteConstantBlocks@
   splitPixelBlocks[ImageData[img], blockSize]

rows = splitRowBlocks /@ cols

rows

Then finally split the columns of each of those:

rowData = Map[splitColumnBlocks[#, 10] &] /@ rows

row splits

That's our data prep. Now theoretically we could just use TextRecognize but...

TextRecognize[ImagePad[First[#], 25, White]] & /@ Flatten @ rowData

{"", "", "", "", "", "", "", "15", "16", "17"}

So we'll have to be a bit smarter about it:

tableHeaders =
 Map[
   Replace[
       TextRecognize[#,
        RecognitionPrior -> "SparseText"
        ],
       "" :>
        TextRecognize[#,
         RecognitionPrior -> "Character"
         ]
       ] &[
     ImageClip[ImagePad[First[#], 25, White], {.95, 1}, {0, 1}]
     ] &
   ] /@ rowData

{{"1", "2", "3", "4", "5"}, {"8", "9"}, {"15", "16", "17"}}

It's slow, but it gets the job done.

Now we find the answers:

getAns[row_, thresh_: .8] :=
 {"A", "B", "C", "D"}[[
   SelectFirst[Range[4],
    Mean@Flatten@ImageData[row[[#]]] < thresh &
    ]
   ]]

Map[getAns@*Rest] /@ rowData

{{"D", "B", "C", "B", "C"}, {"C", "D"}, {"C", "B", "D"}}

And I think that's what you wanted, right?

The second layout is slightly harder, but we can do it in a similar way.

$\endgroup$
  • $\begingroup$ Amazing..It very cool $\endgroup$ – yode Sep 11 '17 at 6:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.