// DLLUsageDemo.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 // #include #include #include "LibEasyOCR-CPP.h" #include #include #include #include #include static const std::set validate_vin_chars = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','J','K','L','M','N','P','R','S','T','U','V','W','X','Y','Z' }; std::string PreProcessVIN(const std::string& vin) { std::string res; for (const auto& chr : vin) { if ((chr == 'i') || (chr == 'I')) res.push_back('1'); else if ((chr == 'o') || (chr == 'O')) res.push_back('0'); else if (chr == 'q') res.push_back('9'); else if (chr == 'Q') res.push_back('0'); else if (validate_vin_chars.count(toupper(chr)) >= 1) res.push_back(toupper(chr)); } return res; } void RecognizeSingleImage(const std::string& img, int image_no) { cv::Mat image = cv::imread(img); if (image.empty()) { std::cout << "RSI: Unable to read image" << std::endl; return; } //cv::blur(image, image, cv::Size(3, 3)); // 1. 灰度 cv::Mat gray; cv::cvtColor(image, gray, cv::COLOR_BGR2GRAY); // 2. 去高光(inpaint) cv::Mat mask = gray > 240; cv::inpaint(gray, mask, gray, 5, cv::INPAINT_TELEA); // 3. 伽马校正(弱化阴影) cv::Mat lut(1, 256, CV_8U); const float gamma = 0.8f; for (int i = 0; i < 256; i++) lut.at(i) = cv::saturate_cast(std::pow(i / 255.0, gamma) * 255); cv::LUT(gray, lut, gray); // 4. CLAHE 局部对比度增强 cv::Ptr clahe = cv::createCLAHE(2.0, cv::Size(8, 8)); clahe->apply(gray, gray); // 2. 形态学 Top-hat & Black-hat 提取高频细节 cv::Mat kernel = cv::getStructuringElement( cv::MORPH_RECT, cv::Size(15, 15)); cv::Mat tophat, blackhat; cv::morphologyEx(gray, tophat, cv::MORPH_TOPHAT, kernel); cv::morphologyEx(gray, blackhat, cv::MORPH_BLACKHAT, kernel); // 3. 高频增强:原图 + tophat - blackhat cv::Mat enhanced; enhanced = gray + tophat - blackhat; // 4. 平滑降噪 cv::GaussianBlur(enhanced, enhanced, cv::Size(3, 3), 0); // 5. 全局 Otsu 阈值 cv::Mat bw; cv::threshold( enhanced, bw, 0, 255, cv::THRESH_BINARY | cv::THRESH_OTSU ); // 保证文字白底黑字 double m = cv::mean(bw.row(bw.rows / 2))[0]; if (m < 128) cv::bitwise_not(bw, bw); // 6. 小核闭运算补笔画断裂 cv::morphologyEx( bw, bw, cv::MORPH_CLOSE, cv::getStructuringElement( cv::MORPH_RECT, cv::Size(3, 3) ), cv::Point(-1, -1), 1 ); // 7. 小核开运算去孤立噪点 cv::morphologyEx( bw, bw, cv::MORPH_OPEN, cv::getStructuringElement( cv::MORPH_RECT, cv::Size(3, 3) ), cv::Point(-1, -1), 1 ); // 8. 转三通道输出 cv::Mat finalBGR; cv::cvtColor(bw, finalBGR, cv::COLOR_GRAY2BGR); cv::Mat output = finalBGR.clone(); cv::imshow("Processed Image " + std::to_string(image_no), output); cv::imwrite("G:\\Users\\15819\\Desktop\\temp\\Processed Image " + std::to_string(image_no) + ".jpg", output); auto results = uns::EasyOCR_CPP::FullAuto(image); for (const auto& [index, info] : results) { const auto& [text, conf, rect] = info; std::string a_text = uns::EOCR_SupportTools::WtoA(text); std::string processed_vin = PreProcessVIN(a_text); printf("RSI(%d): Result %d: Text = {%s(%d) -> |%s|(%d)}, Box = [%d, %d, %d, %d], Confidence = %.3f\n", image_no, (int)index, a_text.c_str(), (int)a_text.length(), processed_vin.c_str(), (int)processed_vin.length(), rect.tl().x, rect.tl().y, rect.br().x, rect.br().y, conf); } if (results.empty()) printf("RSI(%d): No Text Found\n", image_no); } int main() { std::wstring detect_model = L"..\\EasyOCR-CPP\\DetectionModel.onnx"; std::wstring recognize_model = L"..\\EasyOCR-CPP\\RecognitionModel-EN.onnx"; std::vector images = { "G:\\Users\\15819\\Desktop\\error\\UPLOAD-20250709184942-99F24141-6C0A31D2.jpg", "G:\\Users\\15819\\Desktop\\error\\UPLOAD-20250709185025-99F24141-A56037A2.jpg", "G:\\Users\\15819\\Desktop\\error\\UPLOAD-20250709185205-99F24141-1D0C341A.jpg", "G:\\Users\\15819\\Desktop\\error\\UPLOAD-20250709185450-99F24141-EC43D7FD.jpg", "G:\\Users\\15819\\Desktop\\error\\UPLOAD-20250708185403-99F24141-1F2233FA.jpg", "G:\\Users\\15819\\Desktop\\error\\UPLOAD-20250708184942-99F24141-C138BA94.jpg" }; uns::EasyOCR_CPP::GlobalOCRConfig().SetDetectModelPath(detect_model); uns::EasyOCR_CPP::GlobalOCRConfig().SetGPUUsage(uns::easyocr::GPUUsage::CPUOnly); uns::EasyOCR_CPP::SetRecognitionModel(recognize_model, uns::easyocr::CharsetType::EN); if (!uns::EasyOCR_CPP::InitDetectionModel()) { std::cout << "Detector Init Failure!" << std::endl; return -1; } if (!uns::EasyOCR_CPP::InitRecognitionModel()) { std::cout << "Recognizer Init Failure!" << std::endl; return -2; } for (auto&& [index, file] : images | ranges::views::enumerate) RecognizeSingleImage(file, static_cast(index)); cv::waitKey(0); uns::EasyOCR_CPP::CleanupOCR(); return 0; } //VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV