Chào mừng đến với Diễn đàn lập trình - Cộng đồng lập trình.
Trang 1 của 2 12 CuốiCuối
Kết quả 1 đến 10 của 12
  1. #1
    Ngày tham gia
    Sep 2015
    Bài viết
    0

    Kỹ Thuật Nhận Dạng Chữ Viết Tay - Phương pháp và các thực hiện trên C#

    Bài viết này tôi xin trình bày kỹ thuật nhận dạng chữ viết tay bằng phương pháp phân tích đường đi của nét chữ(stroke based):

    Bài viết này hy vọng sẽ giúp các bạn có được cách nhìn tích cực về cách thức nhận dạng chữ viết tay.
    Một phương pháp khác là dùng PCA,các bạn xem topic sau

    Thuật toán PCA trong vấn đề nhận dạng ảnh


    NNLT tôi dùng là C# trên nền Console cho dễ minh họa,các bạn có thể áp dụng cho các nnlt khác 1 cách tương đương về ý tưởng.

    Quá trình nhận dạng cần trải qua các bước sau đây:
    1/Chuyển ảnh về ma trận nhị phân:
    Điều này khá dễ dàng vì ảnh bitmap đều được phân tích ra 3 màu là RGB,tư đó các màu đậm đưa vào matrix là số 1,màu trắng là số 0

    Chuyển về ma trận điểm ảnh nhị phân :


    Mã:
    img = new Bitmap("D:/test.png");for (int i = 0; i < img.Width; i++){    for (int j = 0; j < img.Height; j++)    {        if (img.GetPixel(j, i).A.ToString() == "255" && img.GetPixel(j, i).B.ToString() == "255" && img.GetPixel(j, i).G.ToString() == "255" && img.GetPixel(j, i).R.ToString() == "255")        {            bitstr = bitstr + "0";        }        else        {            bitstr = bitstr + "1";        }    }    bitstr = bitstr + "
    ";}
    bitstr chính là 1 chuỗi chứa toàn bộ các pixel của ảnh bitmap.Các bạn nên dùng các ảnh 50x50 là được.Vượt quá nên
    resize lại.Sau đó chưa vào mảng M có size là 50x50

    2/Khử nhiễu :
    Bạn dùng thuật toán loang để xác định diện tích vùng lớn nhất,sau đó lấy điểm trung tâm của vùng diện tích lớn của khu vực:


    Mã:
    bool b=true;while (b){    if(A[foo, bar].ToString() == "0" || A[foo + level, bar].ToString() == "0" || A[foo - level, bar].ToString() == "0" || A[foo, bar + level].ToString() == "0" || A[foo, bar - level].ToString() == "0" || A[foo + level, bar + level].ToString() == "0" || A[foo - level, bar - level].ToString() == "0" || A[foo + level, bar - level].ToString() == "0" || A[foo - level, bar + level].ToString() == "0"){        break; // lọc các điểm là số 1 và có bao bọc    }    level++;}
    Kết quả thu được như sau:



    3/lọc và chuyển về dạng đỉnh đồ thị rời rạc :


    Mã:
    int l = 2;for (int foo = 1; foo <= 48; foo++){    for (int bar = 1; bar <= 48; bar++)    {        if (M[foo, bar] == 1)        {            int k = 1;            while (k <= l)            {            M[foo + k, bar] = 0;            M[foo, bar + k] = 0;            M[foo - k, bar] = 0;            M[foo, bar - k] = 0;            M[foo + k, bar + k] = 0;            M[foo + k, bar - k] = 0;            M[foo - k, bar + k] = 0;            M[foo - k, bar - k] = 0;            k++;            }        }    }}
    kết quả thu được :


    4/Đánh dấu các đỉnh để dễ phục vụ cho các bước sau :


    5/Xây dựng các vectơ từ các node đến các node của đồ thị :

    điểm này cần chú ý như sau :

    1 đồ thị đã được phân tích ở bước 3 sẽ tạo ra các vecto có hướng đi đến các đỉnh còn lại.
    Tùy vào đường đi của các đỉnh mà ta có được cách nhận dạng.



    Dựa vào đó ta sẽ xác định giữa 2 nút với nhau tạo ra các vecto nào.


    Phân tích các đỉnh kề liên thông trực tiếp với nhau theo vecto nào.Ở đây ta lấy đỉnh kề gần nhất.
    Xác định điểm kề gần nhất:


    Qua hình ta thấy nút số 1 sẽ gần số 4 nhất.

    Vấn đề tiếp theo là xác định vecto từ đỉnh đến đỉnh là vectơ nào :


    Dựa vào đó ta sẽ viết hàm lọc tiếp các đỉnh kề có cùng vecto (nếu không làm bước này thì kết quả phân tích có khác chút nhưng vẫn có thể làm được.Tuy nhiên làm thế này để đơn giản hóa vấn đề hơn)

    VIết đầu ra tổng hợp
    Cái này viết khá khổ vì bạn cần phải tổng hợp dữ liệu liên tục và viết 1 cách kỹ lưỡng và test đầy đủ các trường hợp :

    Bạn sẽ thấy 1 điều rằng,các số 0 6 8 9 sẽ có hình thức gần như sau,các vecto 2,3,4,5 sẽ xuất hiện nhiều lần
    ,ta khoanh vùng lại để viết hàm.Nếu nằm trong 1 khoảng nào đó thì là số 8.Có thể thấy số 8 có 4 đường cong,ta
    lại duyệt từ trái sang phải,từ trên xuống dưới nên vectơ 2,3,4 xuất hiện rất cao,thứ 2 là số 6 và 9,sau là
    số 0 ...

    các vectơ 1 8 sẽ xuất hiện nhiều trong các số 1 7 ..

    từ đó ta sẽ viết hàm liên thuộc,hàm này trả về kết quả gần đúng,từ đó ta suy ra kết quả dự đoán.

    Tham khảo : Handwritten Digits Recognition của tác giả Gaurav Jain, Jason Ko

  2. #2
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Bài viết rất tốt, ... rất hoan nghênh tinh thần của bạn!

    Có nhiều bạn không xem hình ở myopera.com được, bạn lttq đính kèm hình ảnh vào bài viết để tránh mất mát sau này!

  3. #3
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Hay quá, ngày xưa mình làm đến bước
    4/Đánh dấu các đỉnh để dễ phục vụ cho các bước sau. rồi mình dùng kmean để phân thành các cụm cũng nhận dạng được nhưng không chính xác lắm.

    Thank you

  4. #4
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Trích dẫn Gửi bởi Kevin Hoang
    Bài viết rất tốt, ... rất hoan nghênh tinh thần của bạn!

    Có nhiều bạn không xem hình ở myopera.com được, bạn lttq đính kèm hình ảnh vào bài viết để tránh mất mát sau này!
    Đã edit theo lời của anh Kevin

  5. #5
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Cái này giống giống đường cong B-spline nhỉ[IMG]images/smilies/thinking.gif[/IMG]

  6. #6
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Bài này dùng cho môn trí tuệ nhân tạo thì hay đấy nhỉ [IMG]images/smilies/biggrin.png[/IMG].

  7. #7
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Trích dẫn Gửi bởi thansautk
    Hay quá, ngày xưa mình làm đến bước
    4/Đánh dấu các đỉnh để dễ phục vụ cho các bước sau. rồi mình dùng kmean để phân thành các cụm cũng nhận dạng được nhưng không chính xác lắm.

    Thank you
    Bạn có thể post bài của bạn lên cho mình tham khảo với được k?

  8. #8
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    bạn vào đây nhé http://diendan.congdongcviet.com/showthread.php?t=30593

  9. #9
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Rất hay. Thanks bạn nhiều

  10. #10
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    bạn có source code không cho mình xin tham khảo.
    bước 4 và bước 5 mình không hiểu rõ làm sao để ra được như vậy

 

 
Trang 1 của 2 12 CuốiCuối

Quyền viết bài

  • Bạn Không thể gửi Chủ đề mới
  • Bạn Không thể Gửi trả lời
  • Bạn Không thể Gửi file đính kèm
  • Bạn Không thể Sửa bài viết của mình
  •