How can I extract details from credit card images using opencv-python? - image-processing

I want to perform credit card OCR using opencv-python. sample credit card image How can this be done?

This is what is at the top of my head (a very high-level algorithm):
Detect the outline using blob detection (probably verify that you have two sets of parallel lines)
With the two sets of parallel lines, you know how the characters are aligned. Rotate the entire image in that angle, so text would be horizontal (which makes your work simpler)
Perform adaptive binary thresholding (eg. Otsu).
Usually, if you know approximately where to look for information (the co-ordinates relative to the card border), you can use any OCR algorithm when you segment text (binarize it).

Related

Algorithm to detect credit card sized card

I want to detect a credit card sized card in image. The card can be any card eg identity card, member card. Currently, I am thinking to use Canny Edge, Hough Line and Hough Circle to detect the card. But the process will be tedious when I want to combine all the information of Hough Line and Hough Circle to locate the card. Some people suggest threshold and findContour but the color of card can be similar to the background which make this method difficult to achieve the desired result. Is there any kernel and method which can help me to detect the card?
I think, your problem is similar to document scanner. You can refer to this link
Find edges in the image using Canny edge detector (lower and higher thresholds can be set as 0.66*meanIntensity and 1.33*meanIntensity) and do a morphological close operation.
Edge image after performing close
Find the contours in the image using findContours
filterout unwanted contours (I used contourArea to filter contours)
using approxPolyDP approximate the contours to 7 or more points. (I used 0.005 * perimeter as the parameter here)
If you want to find accurate edges, fit lines between the points and get the 4 biggest lines.Find their intersection (since the card may or may not contain curved edges)
You'll end up with the card endpoints which can be used further for homography or to determine the region.
vertices of the card
Edit
Edited the answer to include the steps to obtain the vertices of the card and results are updated.
There are two sub-problems here -
Detect rectangular object in the image.
The rectangular object's actual size should be similar to Credit Card.
For first part, you can try out several methods to extract rectangular region in the image and see which suits your need.
This post shows a lot of methods which you can try out.
In my experience edge detection works best in most cases. Try Canny > Contours with Appoximations > Filter out irrelevant contours > Search for rectangles using some shape detection, template matching or any other methods. Even this post does a similar thing to achieve its task.
Coming to the second point, you cannot find out the size of an object in an image unless you have any reference(known) sized object in the image. If the image was captured from a closer distance, the card will seem larger and if taken from far, the card will seem smaller. So while capturing, you will have to enforce some restrictions like you can ask the user to capture image along with some standard ruler. You can also ask the user to capture image on an A4 sheet with all the sheet edges visible. Since, you know the size of the A4 sheet, you'll be able to estimate the size of the card.
Apart from above methods, if you have enough data set of such images, you can use Haar Classifiers or Neural Network/Deep Learning based methods to do this with much better accuracy.

How to preprocess credit card and extract numbers without background

I'm trying to make a credit card ocr engine like Card.io . But it is very tough to preprocess the card into binary image without noise. I use SWT algorithm but it not works well for all the card. There are variety of credit cards with low contrast background and embossed number. It is very hard to design a common algorithm to preprocess card well for OCR.So dose any one have experience on this kind of card process. The image below is the example of card which is hard for me to preprocess
The thing is that credit cards are on purpose so hard to read (therefore to process). The best I could do was, transforming them to greyscale and add some horizontal sobel filter and then maybe play with some more transformations. And still it was difficult to extract the binary image with the numbers only... And it definitely have different outcome from image to image...
Good luck!
I know i am late but found the solution in adrian rosebrock's blog post over here -
https://www.pyimagesearch.com/2017/07/17/credit-card-ocr-with-opencv-and-python/
The technique is to perform template matching with opencv
then filter the credit card image using grayscale, morphology operations and thresholding.
Then we can find contours of our interest that means contours with relevent height:width ratio.
Once we have got contours of our interest (contours with group of digits) we can again find and extract individual digits. Then we can compare these digits with the digits n our template image.
And in this way we can OCR a credit card

Extract numbers from Image

I have an image for mobile phone credit recharge card and I want to extract the recharge number only (the gray area) as a sequence of number that can be used to recharge the phone directly
This is a sample photo only and cannot be considered as standard, thus the rectangle area may differ in position , in the background and the card also may differ in size .The scratch area may not be fully scratched , the camera's depth and position may differ too . I read a lots and lots of papers on the internet but i can't find any thing that could be interesting and most of papers discuss detection of handwritten numbers .
Any links or algorithms names could be very useful .
You can search the papers on vehicle plate number detection with machine learning methods. Basically you need to extract the number first, you may use sobel filter to extract the vertical edges , then threshold (binary image) and morphologic operations (remove blank spaces between each vertical edge line, and connect all regions that have a high number of edges). Finally retrieve the contour and fill in the connected components with mask.
After you extract the numbers , you can use machine learning method such as neural network and svm to recognize them.
Hope it helps.
Extract the GRAY part from image and then Use Tesseract(OCR) to extract the text written on the gray image.
I think you may not find the algorithm to read from the image on the internet. Nobody will disclose that. I think, if you are a hardcore programmer you can crack that using your own code. I tried from the screenshots where the fonts were clearer and the algorithm was simple. For this, the algorithm should be complex since you are reading from photo source instead of a screenshot.
Follow the following steps:
Load the image.
Select the digits ( By contour finding and applying constraints on area and height of letters to avoid false detections). This will split the image and thus modularise the OCR operation you want to perform.
A simple K - nearest neighbour algorithm for performing the identification and classification.
If the end goal was just to make a bot, you could probably pull the text directly from the app rather than worrying about OCR, but if you want to learn more about machine learning and you haven't done them already the MNIST and CIFAR-10 datasets are fantastic places to start.
If you preprocessed your image so that yellow pixels are black and all others are white you would have a much cleaner source to work with.
If you want to push forward with Tesseract for this and the preprocessing isn't enough then you will probably have to retrain it for this font. You will need to prepare a corpus, process it similarly to how you expect your source data to look, and then use something like qt-box-editor to correct the data. This guide should be able to walk you through the basic steps of retraining.

Analysis and transformation of the image on the basis of this analysis for better OCR results

I have an OCR project, but it works good only with images in which the text is fairly straight, not upside down. (not rotated text)
So I want to make OCR to be able to recognize any kind of images, even upside down. But I don't know what are approaches to solve this problem.
I need something like analysis of lines of letters, but even then I can't identify if line is upside down or not.
If the images you are performing OCR on are from a magazine or book where there is lots of text on multiple lines, I suggest trying to find the rotation of the page.
Probably the simplest way to do this is applying the hough transform for lines. Since the empty space between each line of text should be a a broad white line this could work without any preprocessing of the image. Otherwise try blurring it or using the "close" morphological operation to make the lines of text into opaque blocks.
Once you find the lines in the image with the hough transform you should just extract the principal angle of rotation (like the mean angle of all lines) and rotate it back.
My answer to you will be very high level as this is not simple, as you can imagine. You probably are doing some sort of image segmentation, where you segment each character of your text. But in order to recognize the characters, even when they are rotated, you need to use a feature vector with rotational invariant characteristics. To do it some people are using
Zernike Moment
Neocognitron neural network - widely used for handwriting
I don't think it's a simple task
Not sure if you are creating an OCR engine or using one. Most commercial OCR engines can detect that a page is upside-down (or 90 degree rotated) and auto-rotate it. For example, my company's GlyphReader OCR Engine can do that.
One simple solution is to take a portion of your image and run it through the engine at the four angles until you get back a good amount of recognized text. You can use a dictionary to see if what you are getting back is words and confidence levels to see how sure the engine is of its recognition.
If your engine can report confidence levels, and they are reporting consistently under some threshold, then you should stop and see if the document is rotated.
For 90 and 270, a hough transform will tell you whether the lines in the image are horizontal or vertical. It can also tell you if they are just slightly rotated off the horizontal so that you can correct that as well.

Image processing / super light OCR

I have 55 000 image files (in both JPG and TIFF format) which are pictures from a book.
The structure of each page is this:
some text
--- (horizontal line) ---
a number
some text
--- (horizontal line) ---
another number
some text
There can be from zero to 4 horizontal lines on any given page.
I need to find what the number is, just below the horizontal line.
BUT, numbers strictly follow each other, starting at one on page one, so in order to find the number, I don't need to read it: I could just detect the presence of horizontal lines, which should be both easier and safer than trying to OCR the page to detect the numbers.
The algorithm would be, basically:
for each image
count horizontal lines
print image name, number of horizontal lines
next image
The question is: what would be the best image library/language to do the "count horizontal lines" part?
Probably the easiest way to detect your lines is using the Hough transform in OpenCV (which has wrappers for many languages).
The OpenCV Hough tranform will detect all lines in the image and return their angles and start/stop coordinates. You should only keep the ones whose angles are close to horizontal and of adequate length.
O'Reilly's Learning OpenCV explains in detail the function's input and output (p.156).
If you have good contrast, try running connected components and analyze the result. It can be an alternative to finding lines through Hough and cover the case when your structured elements are a bit curved or a line algorithm picks up the lines you don’t want it to pick up.
Connected components is a super fast, two raster scan algorithm and will give you a mask with all you connected elements in it marked with different labels and accounted for. You can discard anything short ( in terms of aspect ratio). Overall, this can be more general, faster but probably a bit more involved than running Hough transform. The Hough transform on the other hand will be more tolerable for contrast artifacts and even accidental gaps in lines.
OpenCV has the function findContours() that find components for you.
you might want to try John' Resig's OCR and Neural Nets in Javascript

Resources