验证码识别系统实战
核心实现
- 验证码生成器
cpp
include <opencv2/opencv.hpp>
include
include
更多内容访问ttocr.com或联系1436423940
std::string generate_random_text(size_t length = 4) {
static const std::string chars = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789";
static std::random_device rd;
static std::mt19937 gen(rd());
static std::uniform_int_distribution<> dis(0, chars.size()-1);
std::string text;
for(size_t i = 0; i < length; ++i) {
text += chars[dis(gen)];
}
return text;
}
cv::Mat generate_captcha(const std::string& text) {
cv::Mat img(40, 120, CV_8UC3, cv::Scalar(255, 255, 255));
// 绘制文字
int baseline = 0;
auto font = cv::FONT_HERSHEY_SIMPLEX;
cv::Point text_pos(10, 25);
for(size_t i = 0; i < text.size(); ++i) {
std::string char_str(1, text[i]);
cv::putText(img, char_str, text_pos, font, 0.8,
cv::Scalar(0, 0, 0), 1, cv::LINE_AA);
text_pos.x += 30;
}
// 添加干扰线
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(0, 255);
for(int i = 0; i < 3; ++i) {
cv::line(img,
cv::Point(dis(gen)%120, dis(gen)%40),
cv::Point(dis(gen)%120, dis(gen)%40),
cv::Scalar(dis(gen), dis(gen), dis(gen)), 1);
}
return img;
}
2. 模型推理接口(Python)
python
model_api.py
import tensorflow as tf
import numpy as np
import cv2
class CaptchaModel:
def init(self, model_path):
self.model = tf.keras.models.load_model(model_path)
self.chars = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789"
def predict(self, img_array):
img = cv2.resize(img_array, (120, 40))
img = np.expand_dims(img/255.0, axis=(0,-1))
pred = self.model.predict(img)
return ''.join([self.chars[np.argmax(p)] for p in pred[0]])
- C++调用Python模型
cpp
include <Python.h>
include <numpy/arrayobject.h>
std::string predict_captcha(const cv::Mat& img) {
Py_Initialize();
import_array();
// 导入Python模块
PyObject* pModule = PyImport_ImportModule("model_api");
PyObject* pClass = PyObject_GetAttrString(pModule, "CaptchaModel");
PyObject* pInstance = PyObject_CallFunction(pClass, "s", "model.h5");
// 准备图像数据
npy_intp dims[3] = {img.rows, img.cols, img.channels()};
PyObject* pArray = PyArray_SimpleNewFromData(3, dims, NPY_UINT8, img.data);
// 调用预测方法
PyObject* pResult = PyObject_CallMethod(pInstance, "predict", "O", pArray);
// 获取结果
std::string result = PyUnicode_AsUTF8(pResult);
// 清理资源
Py_DECREF(pArray);
Py_DECREF(pResult);
Py_DECREF(pInstance);
Py_DECREF(pClass);
Py_DECREF(pModule);
Py_Finalize();
return result;
}
性能优化
- 多线程处理
cpp
include
include
void batch_predict(const std::vectorcv::Mat& images,
std::vectorstd::string& results) {
size_t num_threads = std:🧵:hardware_concurrency();
std::vectorstd::thread workers;
auto worker_func = [&](size_t start, size_t end) {
for(size_t i = start; i < end; ++i) {
results[i] = predict_captcha(images[i]);
}
};
size_t batch_size = images.size() / num_threads;
for(size_t i = 0; i < num_threads; ++i) {
size_t start = i * batch_size;
size_t end = (i == num_threads-1) ? images.size() : start + batch_size;
workers.emplace_back(worker_func, start, end);
}
for(auto& t : workers) {
t.join();
}
}
2. 内存池优化
cpp
class ImagePool {
public:
ImagePool(size_t pool_size, int width, int height) {
for(size_t i = 0; i < pool_size; ++i) {
pool_.push(cv::Mat(height, width, CV_8UC3));
}
}
cv::Mat acquire() {
std::lock_guard<std::mutex> lock(mutex_);
if(pool_.empty()) {
return cv::Mat(40, 120, CV_8UC3);
}
auto img = std::move(pool_.front());
pool_.pop();
return img;
}
void release(cv::Mat&& img) {
std::lock_guard<std::mutex> lock(mutex_);
pool_.push(std::move(img));
}
private:
std::queuecv::Mat pool_;
std::mutex mutex_;
};
部署方案
- 编译选项
bash
g++ -std=c++17 -O3 -I/usr/include/python3.8 -I/usr/include/opencv4
-lpython3.8 -lopencv_core -lopencv_imgproc -lopencv_highgui
-o captcha_system main.cpp - 系统服务配置
ini
captcha.service
[Unit]
Description=Captcha Recognition Service
After=network.target
[Service]
ExecStart=/usr/local/bin/captcha_system
Restart=always
User=captcha
[Install]
WantedBy=multi-user.target
浙公网安备 33010602011771号