CAPTCHA formation in OpenCV

A CAPTCHA (an acronym for "Completely Automated Public Turing test to tell Computers and Humans Apart") is a type of challenge-response test used in computing to determine whether or not the user is human. It protects your website from spam by means of math logic, easily understood by human beings. You will not have to spend your precious time on annoying attempts to understand hard-to-read words, combinations of letters or pictures that make your eyes pop up.

I have borrowed this source code from here.

Example:

-----------
#include <stdio.h>
#include <stdlib.h>
#include <fstream>
#include <opencv2/opencv.hpp>
#include <cstdlib>
#include <ctime>

using namespace cv;
using namespace std;

const Scalar WHITE = CV_RGB(255,255,255);
const int       CAPTCHA_LENGTH = 8;
const int         CHAR_HEIGHT = 100;
const int         CHAR_WIDTH  = 80;
const string     CHARACTERS[] = {"a", "A", "b", "B", "c", "C", "D", "d", "e", "E", "f", "F", "g", "G",
    "h", "H", "j", "J", "k", "K", "m", "M", "n", "N", "q", "Q", "R", "t", "T", "w", "W", "x", "X", "y", "Y",
    "1", "2", "3", "4", "5", "6", "7", "8", "9"};

void rotate(Mat &input, Mat &output) {

    int sign = rand() % 2;
    if ( sign == 0 ) {
        sign = -1;
    }

    int angle = ( rand() % 30 ) * sign; // between -30 and 30

    Point2f center(input.cols/2.0F, input.rows/2.0F);
    Mat rotationMatrix = getRotationMatrix2D(center, angle, 1.0);

    warpAffine(input, output, rotationMatrix, input.size(),
        INTER_LINEAR, BORDER_CONSTANT, WHITE);

}

void scale(Mat &input, Mat &output, float height, float width) {

    height = ( ( rand() % 20 ) * -1 ) + height;
    width  = ( ( rand() % 20 ) * -1 ) + width;

    Size s(width, height);
    cv::resize(input, output, s);
}

void addLines(Mat &image) {
    rand();
    RNG rng(rand());
    int numLines = CAPTCHA_LENGTH;
    for ( int i = 0; i < numLines; ++i) {
        int startX = rand() % image.cols;
        int endX = rand()   % image.cols;
        int startY = rand() % image.rows;
        int endY = rand()   % image.rows;

        cv::line(image,
            cv::Point(startX, startY),
            cv::Point(endX, endY),
            Scalar(rng.uniform(0, 256),rng.uniform(0, 256),rng.uniform(0, 256)),
            rng.uniform(0, 3), CV_AA); // anti-alias
    }
}

void transform(Mat &charImage) {

    cv::Point2f src[4];
    src[0] = cv::Point2f(0, 0);
    src[1] = cv::Point2f(0, CHAR_HEIGHT);
    src[2] = cv::Point2f(CHAR_WIDTH, 0);
    src[3] = cv::Point2f(CHAR_WIDTH, CHAR_HEIGHT);

    cv::Point2f dst[4];
    dst[0] = cv::Point2f(0, 0);
    dst[1] = cv::Point2f(0, CHAR_HEIGHT);
    dst[2] = cv::Point2f(CHAR_WIDTH, 0);

    int varWidth  = CHAR_WIDTH / 2;
    int varHeight = CHAR_HEIGHT / 2;
    int widthWarp  = CHAR_WIDTH - varWidth + (rand() % varWidth);
    int heightWarp = CHAR_HEIGHT - varHeight + (rand() % varHeight);
    dst[3] = cv::Point2f(widthWarp, heightWarp);

    Mat perspectiveTranx = cv::getPerspectiveTransform(src, dst);
    cv::warpPerspective(charImage, charImage, perspectiveTranx,
        cv::Size(charImage.cols, charImage.rows),
        INTER_CUBIC,
        BORDER_CONSTANT,
        WHITE);
}

void addNoise(Mat &image) {
    rand();
    RNG rng(rand());
    int i,j;
    for (int n = 0; n < 100; n++) {

        i= rand() % image.cols;
        j= rand() % image.rows;

        Point center(i, j);
        circle(image, center, rng.uniform(1, 3),     // radius,
            Scalar(rng.uniform(0, 256),rng.uniform(0, 256),rng.uniform(0, 256)),  // color of noise points
            -2,                  // thickness, negative for filled
            CV_AA);                
    }
}

int main(int argc, char *argv[])
{
    int charactersSize = sizeof(CHARACTERS) / sizeof(CHARACTERS[0]);

    Mat outImage(CHAR_HEIGHT, CHAR_WIDTH * CAPTCHA_LENGTH, CV_8UC3, WHITE);

    srand((unsigned)time(0));
    rand();
    RNG rng(rand());

    
    Scalar color = CV_RGB(0, 0, 0); //255, 127, 80);

    for ( int i = 0; i < CAPTCHA_LENGTH; ++i ) {
        cv::Mat charImage(CHAR_HEIGHT, CHAR_WIDTH, CV_8UC3, WHITE);

        string c = CHARACTERS[rand() % charactersSize];

        putText(charImage, c, Point(10, CHAR_HEIGHT - 10), rng.uniform(1, 6), rng.uniform(3.0, 4.0), color, rng.uniform(1, 5), CV_AA);
        imshow("1st look",charImage);
        transform(charImage);
        imshow("transform",charImage);
        rotate(charImage, charImage);
        imshow("rotate",charImage);
        scale(charImage, charImage, CHAR_HEIGHT, CHAR_WIDTH);
        imshow("scale",charImage);

        charImage.copyTo(outImage(cv::Rect(CHAR_WIDTH * i, 0, charImage.cols, charImage.rows)));
        //waitKey(0);
    }

    addLines(outImage);
    addNoise(outImage);
    double a = rng.uniform(0, 2);
    cout<<"   "<<a<<endl;
    imshow("Captcha11", outImage);
    waitKey(0);

    return EXIT_SUCCESS;
}
-----------

Result:



Sources:
http://en.wikipedia.org/wiki/CAPTCHA

8 comments:

  1. This blog awesome and i learn a lot about programming from here.The best thing about this blog is that you doing from beginning to experts level.

    Love from

    ReplyDelete
  2. Trung tâm dạy kế toán tổng hợp Tại cầu giấy
    Trung tâm dạy kế toán tổng hợp Tại từ liêm
    Trung tâm dạy kế toán tổng hợp Tại thanh xuân
    Trung tâm dạy kế toán tổng hợp Tại hà đông
    Trung tâm dạy kế toán tổng hợp Tại long biên
    Trung tâm dạy kế toán tổng hợp Tại nguyễn chính thanh đống đa
    Trung tâm dạy kế toán tổng hợp Tại minh khai hai bà trưng
    Trung tâm dạy kế toán tổng hợp Tại bắc ninh
    Trung tâm dạy kế toán tổng hợp Tại hải phòng
    Trung tâm dạy kế toán tổng hợp Tại tphcm
    Trung tâm dạy kế toán tổng hợp Tại quận 3
    Trung tâm dạy kế toán tổng hợp Tại thủ đức
    Trung tâm dạy kế toán tổng hợp Tại đà nẵng
    Trung tâm dạy kế toán tổng hợp Tại biên hòa
    Trung tâm dạy kế toán tổng hợp Tại đồng nai
    Trung tâm dạy kế toán tổng hợp Tại nam định
    Trung tâm dạy kế toán tổng hợp Tại thái bình
    Trung tâm dạy kế toán tổng hợp Tại bắc giang
    Trung tâm dạy kế toán tổng hợp Tại vĩnh phúc
    Trung tâm dạy kế toán tổng hợp Tại thái nguyên
    Trung tâm dạy kế toán tổng hợp Tại quảng ninh
    Trung tâm dạy kế toán tổng hợp Tại hải dương
    Trung tâm dạy kế toán tổng hợp Tại hưng yên
    Trung tâm dạy kế toán tổng hợp Tại hà nam
    Trung tâm dạy kế toán tổng hợp Tại ninh bình
    Trung tâm dạy kế toán tổng hợp Tại nghệ an
    Trung tâm dạy kế toán tổng hợp Tại vũng tàu

    ReplyDelete

  3. Thanks for this informative article, I hope you will get most positive response specially for this post. . . .
    โกเด้นสล็อต

    ReplyDelete
  4. تمتعوا الآن بأقوي العروض التي تقدمها لكم شركة تسليك مجارى بالدمام و هي شركة أبراج دبي التي تعتبر واحدة من أهم و أكبر الشركات بالسعودية و تضم أفضل الفرق المتخصصة بالمجال .

    للتواصل الآن عبر :-

    http://abraj-dubai.net/%D8%B4%D8%B1%D9%83%D8%A9-%D8%AA%D8%B3%D9%84%D9%8A%D9%83-%D9%85%D8%AC%D8%A7%D8%B1%D9%89-%D8%A8%D8%A7%D9%84%D8%AF%D9%85%D8%A7%D9%85-%D9%88%D8%A7%D9%84%D9%82%D8%B7%D9%8A%D9%81/

    ReplyDelete
  5. تخلصوا من مشاكل الأجهزة من خلال مركز صيانة ال جي الذي يعتبر الأفضل حيث يضم مركز توكيل صيانة ال جي أفضل المهندسين تواصلوا معهم عبر رقم ال جي فوراً و سوف تحصلون علي أرخص خدمة صيانة أجهزة بمصر .

    للتواصل الآن عبر :-

    http://www.maintenanceg.com/Lg-Agent-Service-Egypt-Center.html

    ReplyDelete
  6. فرص رائعة و فعالة يمكنكم الآن الحصول عليها من خلال شركة ابادة حشرات التي تضم أفضل فريق مكافحة حشرات بمصر و يمكنكم الحصول علي أفضل اسعار شركات مكافحة حشرات بمصر
    من خلال الشركة الفرنسية .
    للتواصل الآن يمكنكم عبر موقعنا هذا :-

    http://www.anti-insects.com

    ReplyDelete