毕业设计项目 深度学习 opencv 公式识别

毕业设计项目 深度学习 opencv 公式识别

文章目录

前言

计算机视觉、图像处理、毕业辅导、作业帮助、代码获取,远程协助,代码定制,私聊会回复!
✍🏻作者简介:机器学习,深度学习,卷积神经网络处理,图像处理
🚀B站项目实战:https://space.bilibili.com/364224477
😄 如果文章对你有帮助的话, 欢迎评论 💬点赞👍🏻 收藏 📂加关注+
🤵‍♂代做需求:@个人主页
在这里插入图片描述

1 课题说明

手写数学公式识别较传统OCR问题而言,是一个更复杂的二维手写识别问题,其内部复杂的二维空间结构使得其很难被解析,传统方法的识别效果不佳。随着深度学习在各领域的成功应用,基于深度学习的端到端离线数学公式算法,并在公开数据集上较传统方法获得了显著提升,开辟了全新的数学公式识别框架。然而在线手写数学公式识别框架还未被提出,论文TAP则是首个基于深度学习的端到端在线手写数学公式识别模型,且针对数学公式识别的任务特性提出了多种优化。

公式识别是OCR领域一个非常有挑战性的工作,工作的难点在于它是一个二维的数据,因此无法用传统的CRNN进行识别。

2 效果展示

这里简单的展示一下效果

3 具体实现

神经网络模型是 Seq2Seq + Attention + Beam Search。Seq2Seq的Encoder是CNN,Decoder是LSTM。Encoder和Decoder之间插入Attention层,具体操作是这样:Encoder到Decoder有个扁平化的过程,Attention就是在这里插入的。具体模型的可视化结果如下

4 关键代码实现

class Encoder(object):
    """Class with a __call__ method that applies convolutions to an image"""
 
    def __init__(self, config):
        self._config = config
 
 
    def __call__(self, img, dropout):
        """Applies convolutions to the image
        Args:
            img: batch of img, shape = (?, height, width, channels), of type tf.uint8
            tf.uint8 因为 2^8 = 256,所以元素值区间 [0, 255],线性压缩到 [-1, 1] 上就是 img = (img - 128) / 128
        Returns:
            the encoded images, shape = (?, h', w', c')
        """
        with tf.variable_scope("Encoder"):
            img = tf.cast(img, tf.float32) - 128.
            img = img / 128.
 
            with tf.variable_scope("convolutional_encoder"):
                # conv + max pool -> /2
                # 64 个 3*3 filters, strike = (1, 1), output_img.shape = ceil(L/S) = ceil(input/strike) = (H, W)
                out = tf.layers.conv2d(img, 64, 3, 1, "SAME", activation=tf.nn.relu)
                image_summary("out_1_layer", out)
                out = tf.layers.max_pooling2d(out, 2, 2, "SAME")
 
                # conv + max pool -> /2
                out = tf.layers.conv2d(out, 128, 3, 1, "SAME", activation=tf.nn.relu)
                image_summary("out_2_layer", out)
                out = tf.layers.max_pooling2d(out, 2, 2, "SAME")
 
                # regular conv -> id
                out = tf.layers.conv2d(out, 256, 3, 1, "SAME", activation=tf.nn.relu)
                image_summary("out_3_layer", out)
                out = tf.layers.conv2d(out, 256, 3, 1, "SAME", activation=tf.nn.relu)
                image_summary("out_4_layer", out)
                if self._config.encoder_cnn == "vanilla":
                    out = tf.layers.max_pooling2d(out, (2, 1), (2, 1), "SAME")
 
                out = tf.layers.conv2d(out, 512, 3, 1, "SAME", activation=tf.nn.relu)
                image_summary("out_5_layer", out)
                if self._config.encoder_cnn == "vanilla":
                    out = tf.layers.max_pooling2d(out, (1, 2), (1, 2), "SAME")
 
                if self._config.encoder_cnn == "cnn":
                    # conv with stride /2 (replaces the 2 max pool)
                    out = tf.layers.conv2d(out, 512, (2, 4), 2, "SAME")
 
                # conv
                out = tf.layers.conv2d(out, 512, 3, 1, "VALID", activation=tf.nn.relu)
                image_summary("out_6_layer", out)
                if self._config.positional_embeddings:
                    # from tensor2tensor lib - positional embeddings
                    # 嵌入位置信息(positional)
                    # 后面将会有一个 flatten 的过程,会丢失掉位置信息,所以现在必须把位置信息嵌入
                    # 嵌入的方法有很多,比如加,乘,缩放等等,这里用 tensor2tensor 的实现
                    out = add_timing_signal_nd(out)
                    image_summary("out_7_layer", out)
        return out

学长编码的部分采用的是传统的卷积神经网络,该网络主要有6层组成,最终得到[N x H x W x C ]大小的特征。

其中:N表示数据的batch数;W、H表示输出的大小,这里W,H是不固定的,从数据集的输入来看我们的输入为固定的buckets,具体如何解决得到不同解码维度的问题稍后再讲;

C为输入的通道数,这里最后得到的通道数为512。

当我们得到特征图之后,我们需要进行reshape操作对特征图进行扁平化,代码具体操作如下:

N    = tf.shape(img)[0]
H, W = tf.shape(img)[1], tf.shape(img)[2] # image
C    = img.shape[3].value                 # channels
self._img = tf.reshape(img, shape=[N, H*W, C])

当我们在进行解码的时候,我们可以直接运用seq2seq来得到我们想要的结果,这个结果可能无法达到我们的预期。因为这个过程会相应的丢失一些位置信息。

位置信息嵌入(Positional Embeddings)

通过位置信息的嵌入,我不需要增加额外的参数的情况下,通过计算512维的向量来表示该图片的位置信息。具体计算公式如下:

其中:p为位置信息;f为频率参数。从上式可得,图像中的像素的相对位置信息可由sin()或cos表示。

我们知道,sin(a+b)或cos(a+b)可由cos(a)、sin(a)、cos(b)以及sin(b)等表示。也就是说sin(a+b)或cos(a+b)与cos(a)、sin(a)、cos(b)以及sin(b)线性相关,这也可以看作用像素的相对位置正、余弦信息来等效计算相对位置的信息的嵌入。

这个计算过程在tensor2tensor库中已经实现,下面我们看看代码是怎么进行位置信息嵌入。代码实现位于:/model/components/positional.py。

def add_timing_signal_nd(x, min_timescale=1.0, max_timescale=1.0e4):
    static_shape = x.get_shape().as_list()  # [20, 14, 14, 512]
    num_dims = len(static_shape) - 2  # 2
    channels = tf.shape(x)[-1]  # 512
    num_timescales = channels // (num_dims * 2)  # 512 // (2*2) = 128
    log_timescale_increment = (
        math.log(float(max_timescale) / float(min_timescale)) /
        (tf.to_float(num_timescales) - 1))  # -0.1 / 127
    inv_timescales = min_timescale * tf.exp(
        tf.to_float(tf.range(num_timescales)) * -log_timescale_increment)  # len == 128 计算128个维度方向的频率信息
    for dim in range(num_dims):  # dim == 0; 1
        length = tf.shape(x)[dim + 1]  # 14 获取特征图宽/高
        position = tf.to_float(tf.range(length))  # len == 14 计算x或y方向的位置信息[0,1,2...,13]
        scaled_time = tf.expand_dims(position, 1) * tf.expand_dims(
            inv_timescales, 0)  # pos = [14, 1], inv = [1, 128], scaled_time = [14, 128] 计算频率信息与位置信息的乘积
        signal = tf.concat([tf.sin(scaled_time), tf.cos(scaled_time)], axis=1)  # [14, 256] 合并两个方向的位置信息向量
        prepad = dim * 2 * num_timescales  # 0; 256
        postpad = channels - (dim + 1) * 2 * num_timescales  # 512-(1;2)*2*128 = 256; 0
        signal = tf.pad(signal, [[0, 0], [prepad, postpad]])  # [14, 512] 分别在矩阵的上下左右填充0
        for _ in range(1 + dim):  # 1; 2
            signal = tf.expand_dims(signal, 0)
        for _ in range(num_dims - 1 - dim):  # 1, 0
            signal = tf.expand_dims(signal, -2)
        x += signal  # [1, 14, 1, 512]; [1, 1, 14, 512]
    return x

得到公式图片x,y方向的位置信息后,只需要要将其添加到原始特征图像上即可。

5 算法综合效果

项目运行效果:

毕业设计 深度学习的公式识别

<think>好的,用户想要寻找与OpenCV相关的毕业设计灵感或资源,特别是项目实例和实现方法。我需要根据他们提供的引用内容来组织回答。首先,引用[1]提到了信用卡号识别、停车场车位识别、文档扫描和答题卡识别项目,而引用[2]则涉及人脸识别、背景替换、图像合成等。这些都可以作为主要的项目方向。 接下来,我需要按照用户的要求,结构清晰地分步骤回答。可能需要先列出项目实例,每个实例下给出实现步骤和技术要点,然后提供实现方法的一般步骤,比如环境搭建、功能模块分解、算法选择等。同时,用户要求生成相关问题,这部分需要放在最后,确保相关问题与主题相关,并且有实际参考价值。 要注意使用正确的中文表达,并且按照系统级指令中的格式要求,行内数学公式用$...$,独立公式用$$...$$,不过在这个回答中可能数学公式不多,但如果有涉及的话需要注意。另外,需要自然地添加引用标识,比如在信用卡号识别后面加上[^1],人脸识别后面加上[^2]。 需要检查是否有遗漏的项目实例,比如引用[1]中的停车场车位识别、文档扫描、答题卡识别,引用[2]中的年龄识别、性别识别、图像修复等,这些都应该被涵盖进去。同时,实现方法部分要简明扼要,指导用户如何开始,比如使用OpenCV的基本函数,结合深度学习模型等。 最后,生成的相关问题需要围绕用户的需求,可能涉及技术选型、优化方法、数据集来源、应用场景等,确保问题有针对性,能够帮助用户进一步探索。</think>以下是为您整理的OpenCV相关毕业设计项目实例及实现方法,结合图像处理与计算机视觉核心技术,提供可落地的研究方向: ### 一、典型OpenCV毕业设计项目实例 1. **信用卡号识别系统** 实现步骤: - 图像预处理:灰度化、二值化、边缘检测(Canny算子) - 数字区域定位:轮廓检测+仿射变换校正 - 字符分割:垂直投影法分割单个数字 - 模板匹配:与标准数字模板库对比识别 技术栈:OpenCV形态学操作+轮廓分析+模板匹配 2. **停车场车位实时检测系统** ```python import cv2 # 车位检测核心代码示例 def detect_parking_space(frame): gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) blurred = cv2.GaussianBlur(gray, (5,5), 0) edges = cv2.Canny(blurred, 50, 150) contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) return [cv2.boundingRect(cnt) for cnt in contours] ``` 3. **人脸属性分析系统** 实现功能: - 人脸检测:Haar级联分类器或Dlib库 - 年龄/性别识别:加载预训练CNN模型 - 背景替换:图像分割+泊松融合 关键技术:OpenCV DNN模块+深度学习模型集成 4. **文档智能扫描系统** 核心算法流程: $$ \text{边缘检测} \rightarrow \text{透视变换} \rightarrow \text{OCR识别} \rightarrow \text{结果输出} $$ ### 二、项目实现通用方法 1. **环境搭建** - Python 3.8+OpenCV 4.5 + NumPy - 可选扩展库:TensorFlow/PyTorch(深度学习集成) 2. **功能模块分解** ```mermaid graph TD A[图像采集] --> B[预处理] B --> C[特征提取] C --> D[模式识别] D --> E[结果可视化] ``` 3. **算法选型建议** | 功能需求 | 推荐算法 | |---|---| | 图像增强 | 直方图均衡化、CLAHE | | 目标检测 | YOLOv5+OpenCV DNN | | 图像分割 | GrabCut算法、U-Net |
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值