We’re rewarding the question askers & reputations are being recalculated! Read more.

Hot answers tagged

97

Here is one example using a convolutional neural network (CNN) to crack the CAPTCHA. We will use a CAPTCHA library to generate sample CAPTCHA images and then train a neural network to decode these images. The trained network can be downloaded from crack_CAPTCHA.wlnet. In the following, we will describe how to prepare the training data, construct and train ...


40

Here is a way of extracting the positions of the various characters in your image by using ImageCorrelate. Define the image to be worked on. image = <your image goes here> Define a set of kernel images to correlate with the image. I use {0,1,2,3,4,5,6,7,8,9,+,-,E,.} scaled to an appropriate size and then rasterised. kernels = Map[ (Style[#, ...


32

For robustness I think it would be best to apply multiple tests and check the results for agreement. Here is one simple test you could include in that suite: f = MorphologicalEulerNumber[Blur @ #, 0.8] &; The function should return 0 for X's and 1 for O's. Quoting the documentation: MorphologicalEulerNumber[image] by default gives the total number ...


30

I get perfect reading using Tesseract using pagesegmode value 6. I did this test after install Tesseract SetDirectory@NotebookDirectory[]; Run["/usr/local/bin/tesseract hex.png hex -psm 6 "] on as hex.png and get with no need to restrict character set (you can see how to do it here) The only mistake are between 0 and O that can be easily corrected as @...


28

Preload all chemical data: ChemicalData[All, "Preload"]; RebuildPacletData[]; (* the latter should not really be necessary *) Get all names: cd = ChemicalData[]; Get their molecular formulae: l = ChemicalData[#, "MolecularFormulaString"] & /@ cd; By counting the Cs, Os and Hs in the tattooed diagram we know we have to find $\rm{C_{19}H_{28}O_{2}}$. ...


26

TextRecognize[] accepts an undocumented Option "SegmentationMode". The allowed values are: ?Image`ExternalOCRDump`$TextRecognizeSegmentationModes { {{3, "Fully automatic page segmentation, but no OSD. (Default)"}}, {{4, "Assume a single column of text of variable sizes"}}, {{6, "Assume a single uniform block of text"}}, {{7, "Treat the image as a ...


25

(* Get your image *) digits = ImagePartition[Import["http://i.stack.imgur.com/cLncR.png"], 50]; (* Remove Borders and Binarize *) d1 = Binarize[ImageCrop[#, 37], .5] & /@ Flatten@digits; (* Keep only images with content (blanks affect the OCR) *) d2 = Select[d1, Min@ImageData@# == 0 &]; (* Assemble as a line and "read" *) TextRecognize@...


25

As I've shown here, TextRecognize[] is a very basic tool and you usually need to tweak it to fit your needs. In your case, you could do something like: i = Binarize@ColorNegate@Import["http://i.stack.imgur.com/lP6Yt.jpg"]; (* Group the chars line by line *) ifc = ImageForestingComponents[ColorNegate@i, Automatic, {First@ImageDimensions@i, 1}]; ClearAll[...


22

TextRecognize seems to be a work in progress, consider the following Rasterize[Graphics[Text[Style["3", 100]]]] // TextRecognize Rasterize[Graphics[Text[Style["a", 100]]]] // TextRecognize Rasterize[Graphics[Text[Style["123", 100]]]] // TextRecognize Rasterize[Graphics[Text[Style["1234", 100]]]] // TextRecognize Rasterize[Graphics[Text[Style["hello", 100]]]]...


21

You more or less said that you weren't interested in a "hand-made" image processing solution, but since TextRecognize is notoriously unreliable, I thought I'd try it anyway. Classify does most of the heavy lifting, so the solution isn't simple, but it's not hard to understand, either. Ok, first step: import the image, adjust for the inhomogeneous lightning ...


19

One can do TextRecognize on screenshots if one increases the dpi (screenshots are usually somewhat like 72dpi - far too low for text recognition). I post this as an answer, because I do not know how to put images in a comment (sorry). In the picture you see increasing accuracy in recognizing the text. I did this in Photoshop, producing images of 300 and 600 ...


18

As I said in the comment, ComponentMeasurements is a easy and robust way to differentiate simple shapes. Using your image and binarizing it: img = ColorConvert[Import["http://i.stack.imgur.com/NbTGY.jpg"], "Grayscale"]; bin = ColorNegate@Binarize[ImageAdjust[GaussianFilter[img, 5]]] ComponentMeasurements calculates a list of measurements for each ...


16

Since the timestamp will always look about the same. This allows us to crop a sample of each individual number to use as the kernel in ImageCorrelate (as suggested by @rm-rf). I use the following method for the image above: (* Define Where to Crop for kernelImages *) imageCropRows = {11, 81}; imageCropColumns = {{726, 802}, {15, 46}, {53, 120}, {433, ...


10

This trick sometimes works: i1 = Import["http://i.stack.imgur.com/gDzKy.png"]; i2 = Import["http://i.stack.imgur.com/LMPQq.png"]; TextRecognize@ImageAssemble[{i1, i2, i1, i2, i1, i2}] (* --> "XOXOXO" *) Use it by appending the unknown square to a bunch of known ones, and detecting the last character.


10

Simple enough, and fails only on one scarcely populated column. Easily fixed if you enforce the "monospaced" property i = Binarize@Import@"http://i.stack.imgur.com/XWhHv.png"; (* delete noisy border*) i1 = DeleteSmallComponents[ImageTake[i, {1, 1650}, {30, -1}], 10]; id = ImageDimensions@i1; cm = ComponentMeasurements[i1, "Centroid"][[All, 2]]; bb = Abs@...


10

a solution to the puzzle: consider each of the 4 wheels as a 16x4 matrix with zeros for all of the "open" or "always covered" areas: wheel1 = { {2, 15, 23, 19, 3, 2, 3, 27, 20, 11, 27, 10, 19, 10, 13, 10}, {22, 9, 5, 10, 5, 1, 24, 2, 10, 9, 7, 3, 12, 24, 10, 9}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...


10

If you are truly interested in this topic, you need to go deeper. TextRecognize uses Tesseract under the hood and getting familiar with how to train its ML algorithm is important in understanding how you can improve the outcome. To make this post not too long, here are the most important information: Tesseract stores the information about recognizing a ...


9

Add Language -> "Portuguese". i = Import["http://i.stack.imgur.com/f3U9N.jpg"] TextRecognize[i, "SegmentationMode" -> 6, Language -> "Portuguese"]


8

Here's a way to augment @georg279's approach. We can use ImageLines to subdivide the image. First we use a derivative filter to highlight the horizontal lines. The parameters need to be tweaked by hand. img = Import@"http://i.stack.imgur.com/Ricz2.png" i2 = Binarize[DerivativeFilter[img, {1, 0}, 0.2], 0.09] Then we can get the lines and inspect them: ...


7

Problem: To recognize numbers on an image and put them in a list using TextRecognize Using the information provided in the question and comments I found the following solution. Solution: img = Import["http://i.stack.imgur.com/BQOAQ.jpg"]; Partition[ Select[ StringSplit@ TextRecognize[LocalAdaptiveBinarize[img, 40, {0.85, 0.07}], "...


7

TextRecognise seems to fare better if you feed it smaller regions. Here I manually isolate individual lines from the table: i0 = Import["http://i.stack.imgur.com/Ricz2.png"]; ImageTake[i0, {60, 73}] Column[TextRecognize[ ImageResize[ImageTake[i0, {#, # + 13}], Scaled[8]]] & /@ Range[60, 360, 16]]


7

Using undocumented TextRecognize options as you can see here, you can do: create a textLinesImg like this: Manipulate[ Column[TextRecognize[Binarize[#, b], "SegmentationMode" -> 7] & /@ textLinesImg] , {{b, 0.9}, 0, 1} , ContinuousAction -> False ]


7

Ok, here is a rather raw intent: (*define a template font*) i = Rasterize@Style[" A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ", FontFamily -> "Courier", FontSize -> 24]; (*separate characters*) cn = ColorNegate /@ Flatten@ImagePartition[i, ImageDimensions[i]/{26, 1}] (*define a function for size adjustment*) let[u_] := ...


7

I felt that I miss some simple way to unite closely located components and finally I found it: ImageForestingComponents (thanks to this answer)! It is unfortunate that a link to this function isn't included in the "See Also" drop-down list neither on the Docs page for ComponentMeasurements, nor MorphologicalComponents, nor MorphologicalTransform. That's ...


6

The basic problem is that the letters I, C and S have the same graph - they all consist of two endpoints (vertices) with a single line (edge) going from one to the other. The shape of the line doesn't change the graph. The only other thing MorphologicalGraph gives you is that the EdgeWeights of the resulting graph correspond to the number of pixels in the ...


6

Maybe something like this: img = Import["https://i.stack.imgur.com/0Jl54.png"] text = TextRecognize @ img del = {"the worst", "of times"}; Rasterize[#, RasterSize -> 1000, ImageSize -> ImageDimensions @ img]& @ Style[#, FontFamily -> "Times"]& @ StringReplace[ text, {del[[1]] -> StringPadRight["", StringLength @ del[[1]]], ...


6

With enhanced in version 11.1 TextRecognize finding positions of recognized text becomes straightforward: testImage = Image[Plot[x, {x, 0, 6 π}, PlotLabel -> "Test plot", BaseStyle -> {FontSize -> 24}]]; res = TextRecognize[testImage, "Block", "BoundingBox", RecognitionPrior -> "SparseText"]; HighlightImage[testImage, {"Boundary", res}] ...


6

This is not a full answer, but it's too extensive to be a comment. Here's a good way to get all of the components using the wonderful MorphologicalComponents, paired with ChanVeseBinarize: img = Import["https://i.stack.imgur.com/rXlxu.jpg"]; binarized = ChanVeseBinarize@img; components = MorphologicalComponents[binarized]; componentNumbers = Rest@...


6

You can use Dilation with rectangular kernel to extend the bounding boxes vertically in order to connect closely related components: MorphologicalTransform[#, "BoundingBoxes", Infinity] & /@ imgs Dilation[#, Table[1, {6}, {1}]] & /@ % With this approach TextRecognize[#, Masking -> Dilation[MorphologicalTransform[#, "BoundingBoxes", ...


5

For this example, it seems that setting the Alpha Channel to .1 yields correct result across all languages without needing to crop. TextRecognize[img ~SetAlphaChannel~ .1, Language -> #] & /@ {"English", "French", "German", "Spanish", "Portuguese", "Italian"} {"12 Catherine FicktEuschAMK", "12 Catherine FicktEuschAMK", "12 Catherine ...


Only top voted, non community-wiki answers of a minimum length are eligible