PageRenderTime 115ms CodeModel.GetById 0ms RepoModel.GetById 0ms app.codeStats 0ms

/SuperLottoScan Prototype/lottoscan.cpp

https://github.com/twelly/OpenCV
C++ | 143 lines | 95 code | 43 blank | 5 comment | 13 complexity | fdf452a2c6630375e9c7af10a395fd64 MD5 | raw file
  1. #include <cv.h>
  2. #include <cvaux.h>
  3. #include <highgui.h>
  4. #include <stdio.h>
  5. struct MatchError {
  6. int digit;
  7. double error;
  8. };
  9. int cmp_match_error(const void* a, const void* b) {
  10. struct MatchError* error_a = (struct MatchError*)a;
  11. struct MatchError* error_b = (struct MatchError*)b;
  12. int ret_val = 0;
  13. if(error_a->error < error_b->error) {
  14. ret_val = -1;
  15. }
  16. else if(error_a->error > error_b->error) {
  17. ret_val = 1;
  18. }
  19. return(ret_val);
  20. }
  21. double pghMatchShapes(CvSeq *shape1, CvSeq *shape2) {
  22. int dims[] = {5, 5};
  23. CvHistogram* hist1 = cvCreateHist(2, dims, CV_HIST_ARRAY, NULL, 1);
  24. CvHistogram* hist2 = cvCreateHist(2, dims, CV_HIST_ARRAY, NULL, 1);
  25. cvCalcPGH(shape1, hist1);
  26. cvCalcPGH(shape2, hist2);
  27. cvNormalizeHist(hist1, 1.0f);
  28. cvNormalizeHist(hist2, 1.0f);
  29. double corr = cvCompareHist(hist1, hist2, CV_COMP_BHATTACHARYYA);
  30. cvReleaseHist(&hist1);
  31. cvReleaseHist(&hist2);
  32. return(corr);
  33. }
  34. void match_template(CvSeq* contours, CvSeq* tmpl_contours) {
  35. int digit_array[] = {9, 8, 6, 7, 5, 4, 3, 2, 0, 1};
  36. struct MatchError match_errors[10];
  37. for(int num_idx = 0; tmpl_contours != 0; tmpl_contours = tmpl_contours->h_next, num_idx++) {
  38. CvRect rect = cvBoundingRect(tmpl_contours);
  39. int area = rect.width * rect.height;
  40. if (area < 400) {
  41. continue;
  42. }
  43. double error = pghMatchShapes(contours, tmpl_contours);
  44. match_errors[num_idx].digit = digit_array[num_idx];
  45. match_errors[num_idx].error = error;
  46. }
  47. qsort(match_errors, 10, sizeof(struct MatchError), cmp_match_error);
  48. printf("Closest match: %d or %d\n", match_errors[0].digit, match_errors[1].digit);
  49. return;
  50. }
  51. int main(int argc, char** argv)
  52. {
  53. char *lotto_ticket_img_file = argv[1];
  54. char *tmpl_0_to_9_img_file = argv[2];
  55. // Load template fle
  56. IplImage* tmpl_0_to_9_img = cvLoadImage(tmpl_0_to_9_img_file, 0);
  57. if(tmpl_0_to_9_img == NULL) {
  58. printf("\nERROR: Failed to load 0 to 9 template image file: %s\n", tmpl_0_to_9_img_file);
  59. return(1);
  60. }
  61. // Load ticket image
  62. IplImage* lotto_ticket_img = cvLoadImage(lotto_ticket_img_file, 0);
  63. if(lotto_ticket_img == NULL) {
  64. printf("\nERROR: Failed to load ticket image file: %s\n", lotto_ticket_img_file);
  65. return(1);
  66. }
  67. IplImage* tmp_ticket_img = cvCreateImage(cvGetSize(lotto_ticket_img), lotto_ticket_img->depth, 1);
  68. // Pre-process images
  69. cvThreshold(tmpl_0_to_9_img , tmpl_0_to_9_img , 100, 255, CV_THRESH_BINARY);
  70. cvThreshold(lotto_ticket_img, lotto_ticket_img, 100, 255, CV_THRESH_BINARY_INV);
  71. cvNamedWindow("Temporary");
  72. // Find contours
  73. CvSeq* contours = 0;
  74. CvSeq* tmpl_contours = 0;
  75. CvSeq* low_contours = 0;
  76. CvSeq* low_tmpl_contours = 0;
  77. CvMemStorage* storage = cvCreateMemStorage(0);
  78. cvFindContours(tmpl_0_to_9_img , storage, &tmpl_contours, sizeof(CvContour), CV_RETR_CCOMP, CV_CHAIN_APPROX_NONE);
  79. cvFindContours(lotto_ticket_img, storage, &contours , sizeof(CvContour), CV_RETR_CCOMP, CV_CHAIN_APPROX_NONE);
  80. low_contours = cvApproxPoly(contours , sizeof(CvContour), storage, CV_POLY_APPROX_DP, 1, 1);
  81. low_tmpl_contours = cvApproxPoly(tmpl_contours, sizeof(CvContour), storage, CV_POLY_APPROX_DP, 1, 1);
  82. for(; low_contours != 0; low_contours = low_contours->h_next) {
  83. CvRect rect = cvBoundingRect(low_contours);
  84. int area = rect.width * rect.height;
  85. if (area < 400) {
  86. continue;
  87. }
  88. cvDrawContours(tmp_ticket_img, low_contours, cvScalarAll(255), cvScalar(255), 0, 1);
  89. cvShowImage("Temporary", tmp_ticket_img);
  90. match_template(low_contours, low_tmpl_contours);
  91. cvWaitKey(0);
  92. }
  93. // Cleanup
  94. cvReleaseMemStorage(&storage);
  95. cvReleaseImage(&tmpl_0_to_9_img);
  96. cvReleaseImage(&lotto_ticket_img);
  97. cvReleaseImage(&tmp_ticket_img);
  98. cvDestroyWindow("Temporary");
  99. return(0);
  100. }