识别_识别条形码 - CSDN
精华内容
参与话题
  • 基于Opencv的口罩佩戴识别系统

    万次阅读 多人点赞 2020-03-21 09:44:46
    人脸识别技术以及非常普及啦,现在的支付宝戴口罩也可以识别,据报道阿里现在正在尝试主导人脸识别技术某些标准。在商业上大多数公司会选择国内AI大咖,比如百度智能云、阿里智慧云、华为云、腾讯云等等。这些平台的...

    疫情之下,有人选择负重前行,有人在年假与工作中毅然选择后者。感谢“疫”路有你,祝愿祖国繁荣昌盛,国泰民安!

    人脸识别技术已经非常普及啦,现在戴口罩的脸支付宝也可以识别,据报道阿里现在正在尝试主导人脸识别技术的某些标准。在商业上大多数公司会选择国内AI大咖,比如百度智能云、阿里智慧云、华为云、腾讯云等等。这些平台的AI解决方案可以说代表了中国AI的最高水平。那么不使用他们提供的技术我们能不能做相关方面的开发呢?我的答案是可以!不吹不黑,其效果适用于精度要求不是很高的场景,满足一般需求。当然无法比拟这些巨头公司!

    特殊时期在某些场合,比如药店、菜市场门口有无私的工作人员提醒戴口罩、测量体温。那么对于是否戴口罩能不能交给计算机去完成呢?我们只需要一台电脑一个摄像头就行,当然实际比这要复杂很多,需要考虑很多非技术上面的因素。今天我们只从这一技术层面使用开源社区的计算机视觉库OpenCv解决。

    所以我的想法就是这样:

    下面就按照以上的步骤去实现,分为以下几个阶段:

    环境的搭建:

    所需环境:OpenCv-Python,Python3.0版本  

    安装Opencv参考 零一样的存在  的博客

    开启摄像头并检测出人脸:

    OpenCv在Python中的导入是cv2,直接调用即可完成前面三个步骤:原理其实很简单,如果你运行了下面的代码就能够发现,其实只是一个循环不断读摄像头的每一帧,然后灰度处理,再进行人脸检测。一张图片它之所以能够识别人脸,是因为有这样一个文件haarcascade_frontalface_default.xml 这个模型描述文件非常重要,这是OpenCv自带的人脸识别模型文件,当然还有自带其他的xml文件,比如笑脸识别,猫脸识别,眼睛识别等等,需要这个文件的话可以到 haarcascades下载一下,然后把它复制到项目就好。不过非常遗憾没有口罩人脸识别,不然就非常简单了。因此我们就需要自己去训练构造出一个这样的人脸口罩xml模型。

    import cv2
    #识别人脸的xml文件,构建人脸检测器
    detector= cv2.CascadeClassifier('haarcascades\\haarcascade_frontalface_default.xml')
    #获取0号摄像头的实例
    cap = cv2.VideoCapture(0)
    
    while True:
        # 就是从摄像头获取到图像,这个函数返回了两个变量,第一个为布尔值表示成功与否,以及第二个是图像。
        ret, img = cap.read()
        转为灰度图
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        #获取人脸坐标
        faces = detector.detectMultiScale(gray, 1.1, 3)
        for (x, y, w, h) in faces:
            #参数分别为 图片、左上角坐标,右下角坐标,颜色,厚度
            cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 2)
        cv2.imshow('Cheney', img)
        cv2.waitKey(3)
    
    cap.release()
    cv2.destroyAllWindows()

    训练分类器:

    说明白一点,OpenCv是开源的,大家都可以使用,无需缴费。那就意味着它的精度不够高,鲁棒性差等缺点。不然就不会有那么多公司自主研发自己的人脸识别技术了。作为学生阶段使用OpenCv非常足够了,要知道OpenCv是一本非常厚的书,看完得费很大力气噢。我们目前研究的只是他的运用而非原理,如要深究原理的话,那就难受多了,这也许就把学硕与专硕区分开来了,这样理解如有偏差请批正!

    数据预处理:

    首先我们得去获取带了口罩的图片以及未戴口罩的人脸图片,我们把戴了口罩的照片看作正样本,未戴口罩的图片看作负样本。不妨先看下我收集到样本吧!左边是戴了口罩的图片,右边是未戴口罩的图片。我发现了一个现象,收集到的戴口罩图片基本上是女性的,可能与喜欢自拍有相关性,没研究哈哈。本来想直接用下面图片进行训练,可是一想到OpenCv不太准确,而且噪音样本影响非常大。我可能要将数据处理的干净才能保证准确性。想要照片的同学可以到这来下载

    第一步:将所有照片的命名统计到Excel表格,这样便于循环遍历读取处理每一张照片。操作方法是:打开cmd,cd进所有照片的上级目录,然后敲下面的命令:

    dir /b/s/p/w *.jpg > pos.txt

    我所有照片放在文件夹1下面就这样操作:

    然后跑到1文件夹下面去,会发现这样一个txt文本,里面记录里该文件夹下所有文件名,复制到Excel里面就可以在Python中读取文件路径了。如下图:

    第二步:我们直接拿这些戴口罩的照片去训练是不行的,因为一整张照片脸和口罩的比例非常小。其他部位比如手、肩膀、等等动作都是噪音,我们并不需要拿去训练,它不但会增加CPU的计算量还会干扰模型。所有我们要进行裁减处理,裁减出戴口罩的人脸,因为OpenCv识别人脸时有些误差,我们需要手动删除不合格的口罩人脸灰度图。正样本:仅包含被检测物体的样本,并且距离边界尽量要小,图片尺寸大小一致。负样本:不包含被检测物体的样本,图片尺寸大小无要求。在裁减的时候顺便灰度处理。如下:

    下面是负样本,照片用于学习交流,不存在盈利目的,所以我认为不构成侵权行为,不过向我发律师函的话我立马删,真的!因为我怂!公民享有肖像权,未经本人同意,不得以营利为目的使用公民的肖像。”构成侵犯公民肖像权的行为,通常应具备两个要件:一是未经本人同意;二是以营利为目的。常见的侵犯公民肖像权的行为,主要是未经本人同意、以营利为目的使用他人肖像做商业广告、商品装潢、书刊封面及印刷挂历等。 好吧有点扯远了!

    import pandas as pd
    import cv2
    names=pd.read_excel('data\\imgName.xlsx')['names']# 读取所有照片名字
    i=100000 #用于重新命名
    for imagepath in names:
        #读取图片
        img = cv2.imread(imagepath)
        #转成灰度
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        #人脸识别器
        detector = cv2.CascadeClassifier('haarcascades\\haarcascade_frontalface_default.xml')
        #获取人脸位置
        faces = detector.detectMultiScale(gray, 1.1, 5)
        for (x, y, w, h) in faces:
            #裁减图片
            gray = gray[y:y+h,x:x+w]  # 裁剪坐标为[y0:y1, x0:x1]
            #如果人脸不为空
            try:
                # 保存裁减后的灰度图
                cv2.imwrite('Q:\\GraduationProject\\mask\\gray1\\'+str(i)+'.jpg', gray)
                # cv2.waitKey(3000)
                i += 1
            except:
                print()
    

    第三步:使得正样本的所有照片的像素一致(必须一致)这里使用50X50的像素,负样本的像素一定要大于50X50.

    import pandas as pd
    import cv2
    
    for n in range(100000,100352):
        path='Q:\\GraduationProject\\mask\\gray1_2\\'+str(n)+'.jpg'
        # 读取图片
        img = cv2.imread(path)
        img=cv2.resize(img,(50,50))
        cv2.imwrite('Q:\\GraduationProject\\mask\\gray1_2\\' + str(n) + '.jpg', img)
        n += 1

    并且在后面添加 1 0 0 50 50 (使用全部替换)pos.txt文件如下图所示:这里1表示当前图片重复出现的次数是1, 0 0 50 50表示目标图片大小是矩形框从(0,0)到(50,50)。 负样本只需要前面一列路径,后面不需要!(纠正一下,后来我调成了20X20的,因为官方推荐20X20)

    以下有些是参考https://blog.csdn.net/qq_32502511/article/details/79010509这篇文章,告知侵删!

    第四步:获取供训练的vec文件。先介绍一下我们的主角 opencv_createsamples.exe ,它位于OpenCV\build\x64\vc14\bin下面,它是用于创建样本描述文件,后缀名是.vec。专门为OpenCV训练准备,只有正样本需要,负样本不需要。opencv_traincascade.exe:是OpenCV自带的一个工具,封装了haar特征提取LBP和HOG特征分类器 。老版本有opencv_traincascade.exe,今天我们不用它。

     一般来说,正负样本数目比例为1:3时训练结果较好,但是不是绝对。由于每个样本的差异性不同等因素,所以没有绝对的比例关系。但是负样本需要比正样本多,因为原则上说负样本的多样性越大越好,我们才能有效降低误检率,而不仅仅是通过正样本的训练让其能识别物体。在本次训练中,我选择了350个正样本和1100个负样本,均为灰度图像。

    创建正样本vec文件

    opencv_traincascade训练的时候需要输入的正样本是vec文件,所以需要使用createsamples程序来将正样本转换为vec文件。完成以上工作就前往主角 opencv_createsamples.exe 目录下OpenCV\build\x64\vc14\bin,复制pos.txt 和 neg.txt到该目录下:然后cmd进入该目录

    opencv_createsamples.exe -vec pos.vec -info pos.txt -num 353 -w 20 -h 20

     

    说明:

    -info,指样本说明文件

    -vec,样本描述文件的名字及路径

    -num,总共几个样本,要注意,这里的样本数是指标定后的20x20的样本数,而不是大图的数目,其实就是样本说明文件第2列的所有数字累加

    -w -h指明想让样本缩放到什么尺寸。

    如图:得到pos.vec文件

    训练样本新建文件traincascade.bat

    opencv_traincascade.exe -data xml -vec pos.vec -bg neg.txt -numPos 500 -numNeg 656 -numStages 20 -w 20 -h 20 -mode ALL

    pause

    复制进去保存,把pos.txt和neg.txt改回如图格式(注意:这一步至关中重要)并且还要新建xml文件夹!

    运行traincascade.bat等待就能得到xml文件:

    如果出错了就参考这位博主的博客吧!

    HR 是击中率(理解为模型猜对了的概率吧!),FA是 虚警率(也就是虚报率吗?理解为模型搞错了的概率吧)不是太懂,个人这样理解,反正击中率越高虚警率越低这个模型比较好,但也要考虑泛化嘛?懂的朋友赐教一下哈,只有当每一层训练的FA低于你的命令中声明的maxfalsealarm数值才会进入下一层训练。前面10层比较快,后面就非常慢了。但是心情非常开心,就像看着自己小心翼翼抚养的一个小宝贝马上要长大了的感觉,哈哈哈哈哈哈哈哈哈。小骄傲!

    虚警率已经达标不再进行训练!下面使用训练出来的xml来进行戴口罩人脸识别!

     

    最后的效果还不错,没戴口罩根本识别不出,戴了口罩识别需要在光线明亮下才能很好识别,否则的话效果不是非常nice。毕竟只用了330张正样本,找个时间跑一下1000样本,300正样本跑了将近两个小时,期间还中断了几下。总的来说效果达到了预期,以后尝试训练一千以上的正样本。

    import cv2
    detector= cv2.CascadeClassifier('haarcascades\\haarcascade_frontalface_default.xml')
    mask_detector=cv2.CascadeClassifier('data\\cascade.xml')
    cap = cv2.VideoCapture(0)
    
    while True:
        ret, img = cap.read()
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        faces = detector.detectMultiScale(gray, 1.1, 3)
        for (x, y, w, h) in faces:
            #参数分别为 图片、左上角坐标,右下角坐标,颜色,厚度
            face=img[y:y+h,x:x+w]  # 裁剪坐标为[y0:y1, x0:x1]
            mask_face=mask_detector.detectMultiScale(gray, 1.1, 5)
            for (x2,y2,w2,h2) in mask_face:
                cv2.rectangle(img, (x2, y2), (x2 + w2, y2 + h2), (0, 0, 255), 2)
    
        cv2.imshow('Cheney', img)
        cv2.waitKey(3)
    
    cap.release()
    cv2.destroyAllWindows()

    附上跑出来的  cascade.xml  文件!最后感谢所有负重前行的追梦人,加油!

    后面发现摘下眼镜的识别准确度大大提高,吓到我了!原因就是 泛化能力太强了,因为正样本没有戴眼镜的图片,所有后期改进应当适当加入戴眼镜戴口罩的图片。然后负样本应该具有广泛性,不仅仅是人脸,还可以加上身体。然后提高训练数量。这个模型应该可以达到非常好的效果。

    附上两张效果对比照片:

     

     

    展开全文
  • 车辆检测识别(YOLOV2)

    万次阅读 2018-07-26 19:04:05
    代码地址:yang1688899/Vehicle-Detection-YOLO-keras YOLO简介: YOLO意为 You Only Look Once,是一种基于深度学习的端对端(end to end)物体检测方法.与R-CNN,Fast-R-CNN,Faster-R-CNN等通过region proposal...

     

    代码地址:yang1688899/Vehicle-Detection-YOLO-keras

    YOLO简介:

    YOLO意为 You Only Look Once,是一种基于深度学习的端对端(end to end)物体检测方法.与R-CNN,Fast-R-CNN,Faster-R-CNN等通过region proposal产生大量的可能包含待检测物体的 potential bounding box,再用分类器去判断每个 bounding box里是否包含有物体,以及物体所属类别的方法不同,YOLO将物体检测任务当做一个regression问题来处理.

    YOLO检测思路:

    (这里以输入为416x416的YOLOV2为例)

    首先将图片划分为13x13个栅格(grid cell):

     

     

    每个栅格负责预测5个bounding box(bounding box包括中心点坐标x,y及其宽w,高h,共4个值)。对于每个bounding box预测其是否包含物体的confidence score(1个值),及其所包含物体class的possibility分布(由于有20个class,这里有20个值)。最终模型的的输出为13x13x125.这里13x13对应13x13个栅格(grid cell).每个bounding box 一共有4+1+20=25个值,每个栅格检测5个bounding box,则有每个栅格对应5x25=125个值,因此13x13x125.

    以下为每个栅格的对应输出:

     

     

    模型最终检测到13x13x5=845个bounding box把所有的bounding box都画到原图上可能会是这样子的:

     

     

    大多数的bounding box 的confidence score都是非常低的(也就是没有检测到物体的),只要少数的bounding box 是高confidence score的,检测到物体的。通过confidence score与最大的class的possibility相乘可以得到该bounding box 包含某物体的置信度,对这一置信度进行阈值过滤可以把大部分无意义的bounding box过滤掉。剩下的bounding box 可能存在的多重检测问题(即一个物体被多个bounding box检测)可以用NMS,heatmap等方法进行过滤整合,得到最终检测结果。

    经过过滤处理的检测结果会是这样的:

     

     

    实现步骤

    ps:本来是打算keras构建模型结构,然后加载weights文件训练后了参数实现的,但一直没有搞清楚weights文件的参数是怎么和模型各层对应上,最后找了YAD2K,里面提供了把YOLOV2 weights文件直接转换成keras model文件的方法,就直接拿来用了。

    • 使用YAD2K把weights文件转化为keras的h5文件
    • 使用model预测bounding box
    • 阈值筛选bounding box

    使用YAD2K把weights文件转化为keras的h5文件

    下载相应的YOLO weights和cfg文件:

    weight文件下载;

    获得YAD2K;

    运行yad2k.py文件,参数依次为:cfg文件路径,weights文件路径,model文件输出路径.

    这里使用yolov2-tiny模型的voc版本,运行如下命令:

    python ./yad2k.py ./yolov2-tiny-voc.cfg ./yolov2-tiny-voc.weights ./model/yolov2-tiny-voc.h5
    

    使用model预测bounding box

    这里是一个使用keras的predict_generator对视频进行预测的示例(在内存显存足够的情况下可以直接用predict):

    首先使用opencv读取视频,并进行resize,normalize等预处理:

    #把给定视频转换为图片
    def preprocess_video(src_path):
        cap = cv2.VideoCapture(src_path)
        num_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
        fps = int(cap.get(cv2.CAP_PROP_FPS))
        fourcc = int(cap.get(cv2.CAP_PROP_FOURCC))
        video_frames = []
        for i in range(num_frames):
            ret, frame = cap.read()
            if ret:
                frame = cv2.resize(frame, (416, 416))
                frame = preprocess_image(frame)
                video_frames.append(frame)
        video_frames = np.array(video_frames)
        cap.release()
        return video_frames,num_frames,fps,fourcc
    

    利用yield写一个generator function,用于在预测时生成指定batch_size大小的图片batch:

    #prediction_generator
    def video_batch_gen(video_frames,batch_size=32):
       for offset in range(0,len(video_frames),batch_size):
           yield video_frames[offset:offset+batch_size]
    

    最后加载model,使用predict_generator进行预测:

    video_frames, num_frames, fps, fourcc = utils.preprocess_video(src_path)
    gen = utils.video_batch_gen(video_frames,batch_size=batch_size)
    
    model = load_model("./model/yolov2-tiny-voc.h5")
    
    print("predicting......")
    predictions = model.predict_generator(gen)
    

    阈值筛选bounding box

    得到predictions后,还要对predictions进行进一步处理,目的是过滤掉置信度低的及重叠的bounding box,使得图片的每一个物体对应一个置信度最高的bounding box。 为了方便对predictions进行处理,这里定义一个box类对bounding box的参数进行存储:

    class Box:
        def __init__(self):
            self.w = float()
            self.h = float()
            self.p_max = float()
            self.clas = int()
            self.x1 = int()
            self.y1 = int()
            self.x2 = int()
            self.y2 = int()
    

    模型预测的是bounding box的中心点坐标x,y及其宽w,高h及是否包含物体的confidence score和其所包含物体class的possibility,其中中心点坐标x,y及其宽w,高h都是相对于每个栅格(grid cell)而言的,因此这些参数都需要进行转换。使用confidence score与最大的class的possibility相乘可以得到置信度,对这个置信度进行一些阈值过滤可以过滤掉置信度不高的bounding box:

    prediction = np.reshape(prediction, (n_grid, n_grid, n_box, 5+n_class))
    boxes = []
    for row in range(n_grid):
        for col in range(n_grid):
            for b in range(n_box):
                tx, ty, tw, th, tc = prediction[row, col, b, :5]
                box = Box()
    
                box.w = np.exp(tw) * anchors[2 * b + 0] * 32.0
                box.h = np.exp(th) * anchors[2 * b + 1] * 32.0
    
                c_probs = softmax(prediction[row, col, b, 5:])
                box.clas = np.argmax(c_probs)
                box.p_max = np.max(c_probs) * sigmoid(tc)
    
                center_x = (float(col) + sigmoid(tx)) * 32.0
                center_y = (float(row) + sigmoid(ty)) * 32.0
    
                box.x1 = int(center_x - (box.w / 2.))
                box.x2 = int(center_x + (box.w / 2.))
                box.y1 = int(center_y - (box.h / 2.))
                box.y2 = int(center_y + (box.h / 2.))
    
                if box.p_max > probs_threshold:
                    boxes.append(box)
    

    经过初步处理后的bounding box仍会有大量重叠的情况:

     

     

    这里使用非极大值抑制(NMS)对bounding box进行过滤(ps:也可以使用车辆识别(特征提取+svm分类器)中介绍的heatmap进行过滤,只要达到使每个物体对应一个合适的bounding box的目的):

    #使用non_maxsuppression 筛选box
    def non_maximal_suppression(thresholded_boxes, iou_threshold=0.3):
        nms_boxes = []
        if len(thresholded_boxes) > 0:
            # 添加置信度最高的box
            nms_boxes.append(thresholded_boxes[0])
    
            i = 1
            while i < len(thresholded_boxes):
                n_boxes_to_check = len(nms_boxes)
                to_delete = False
    
                j = 0
                while j < n_boxes_to_check:
                    curr_iou = iou(thresholded_boxes[i], nms_boxes[j])
                    if (curr_iou > iou_threshold):
                        to_delete = True
                    j = j + 1
    
                if to_delete == False:
                    nms_boxes.append(thresholded_boxes[i])
                i = i + 1
    
        return nms_boxes
    

    最后把过滤后的bounding box展示在图片上,以下为示例代码:

    #在图片上画出box
    def draw_boxes(image,boxes):
        for i in range(len(boxes)):
            color = colors[boxes[i].clas]
            best_class_name = classes[boxes[i].clas]
    
            image = cv2.rectangle(image, (boxes[i].x1, boxes[i].y1),
                                        (boxes[i].x2, boxes[i].y2),color)
    
            cv2.putText(
                image, best_class_name + ' : %.2f' % boxes[i].p_max,
                (int(boxes[i].x1 + 5), int(boxes[i].y1 - 7)), cv2.FONT_HERSHEY_SIMPLEX, 0.5,
                color, 1)
    
        return image
    

    结果:

     

    展开全文
  • java指纹识别

    千次下载 热门讨论 2020-07-30 23:32:45
    java指纹识别 java识别 图片匹配
  • 基于matlab的车牌识别系统设计

    万次阅读 多人点赞 2020-06-04 17:29:17
    一个完整的车牌号识别系统要完成从图像采集到字符识别输出,过程相当复杂,基本可以分成硬件部分跟软件部分,硬件部分包括系统触发、图像采集,软件部分包括图像预处理、车牌定位、字符分割、字符识别四大部分,一个...

           一个完整的车牌号识别系统要完成从图像采集到字符识别输出,过程相当复杂,基本可以分成硬件部分跟软件部分,硬件部分包括系统触发、图像采集,软件部分包括图像预处理、车牌定位、字符分割、字符识别四大部分,一个车牌识别系统的基本结构如图:

     

    图像预处理

        在图像预处理之前,首先要了解什么是RGB图像、灰度图像、二值化图像,以及他们如何转换。

    RGB图像:又称彩色图像,RGB色彩就是常说的三原色,R代表Red(红色),G代表Green(绿色),B代表Blue(蓝色)。自然界中肉眼所能看到的任何色彩都可以由这三种色彩混合叠加而成,RGB图像用三维数组表示,最后一维长度为3,(1,2,3分别表示RGB三个分量),对于每一个分量,数值范围也是0~255。红、绿、蓝三个通道的缩略图,都是以灰度显示的,用不同的灰度色阶来表示“ 红,绿,蓝”在图像中的比重。通道中的纯白,代表了该色光在此处为最高亮度,亮度级别是255,0表示亮度最低,255表示亮度最亮。只有三个通道同时有值才可以显示出彩色(如红色通道显示为红色)。所以车牌原始图像是RGB图像。

    灰度图像:是每个像素只有一个采样颜色的图像,这类图像通常显示为从最暗黑色到最亮的白色的灰度,尽管理论上这个采样可以任何颜色的不同深浅,甚至可以是不同亮度上的不同颜色。灰度图像的每个像素只有一个亮度信息的单色图像。其中的亮度信息,采样自从白色与黑色之间划分的若干等级。我们常说的灰度阶,就是从白色到黑色划分的等级数。一般为2^n,常用的灰度阶为256,用单个字节(8bit,256=2^8)就可以存储每一个灰度值,灰度图像用二维数组表示。

    二值化图像,又称黑白图像,顾名思义是由黑色和白色两种颜色表示的图像。即图像上的像素点的灰度值设置为0或255。

    将彩色图像(RGB图像转化为灰度图像的过程称为图像灰度化。要表示灰度图,就需要把亮度值进行量化,有四种方法:见表1

    表1

    序号

    方法

    方法论述

    灰度化优点

    1

    分量法

    将彩色图像中的三分量的亮度作为三个灰度图像的灰度值,可根据应用需要选取一种灰度图像。

    1.RGB的值都一样。

    2图像数据即调色板索引值,就是实际的RGB值,也就是亮度值。

    3因为是256色调色板,所以图像数据中一个字节代表一个像素,很整齐。

    2

    最大值法

    将彩色图像中的三分量亮度的最大值作为灰度图的灰度值

    3

    均值法

    将彩色图像中的三分量亮度求平均得到灰度图的灰度值

    4

    加权平均法

    根据重要性及其它指标,将三个分量以不同的权值进行加权平均,常见的算法:

    f(i,j)=0.30R(i,j)+0.59G(i,j)+0.11B(i,j)

     


    图像的二值化有利于图像的进一步处理,使图像变得简单,而且数据量减小,能凸显出感兴趣的目标的轮廓。在matlab中,二值化图像常常为0和1数组表示,二值化的常用算法有几种,见表2

                                                                                        表2

    序号

    方法

    方法论述

    1

    全局二值化方法

    对每一幅图计算一个单一的阀值。灰度级大于阈值的像素被标记为背景色,否则为前景。

    2

    局部自适应二值化

    以像素的邻域的信息为基础来计算每一个像素的阈值。其中一些方法还会计算整个图像中的一个阈值面。如果图像中的一个像素(x,y)的灰度级高于在(x,y)点的阈值面的计算值,那么把像素(x,y)标记为背景,否则为前景字符。

     

     

    基于车牌颜色特征的定位方法

    本文给出的是一种基于颜色特征的定位算法,该算法不用对整幅图像进行边缘检测,而是直接寻找图片中颜色、形状及纹理符合车牌特征的连通区域。通过对大量车牌图像的分析,可以发现对于具有某种目标色的像素,可以直接通过对H、s、v三分量设定一个范围来把它们过滤出来,无需进行较复杂的色彩距离计算,这样可以在色彩分割时节省大量的时间。这种过滤对蓝色和黄色车牌特别有效,但对于黑色和白色的过滤效果不是很理想。这是因为对于纯色的黑色和白色,它们的色调和饱和度没有意义,所以和其它颜色相比缺少了两个过虑指标。

    通过实验数据表明,汽车车牌的HSV值可由下表确定

    表3 HSV的取值范围

     

    蓝色

    黄色

    白色

    黑色

    色调

    200~255度

    25~55度

    \

    \

    饱和度

    0.4~1

    0.4~1

    0~0.1

    \

    亮度

    0.3~1

    0.3~1

    0.9~1

    0~0.35

    注:“\”表示不予考虑的项目。

     

    由于该算法的原理特殊,决定了主要针对家庭小型车蓝底白字车牌进行识别。根据彩色图像的RGB比例定位出近似蓝色的候选区域。但是由于RGB三原色空间中两点间的欧氏距离与颜色距离不成线性比例,在设定蓝色区域的定位范围时不能很好的控制。因此造成的定位出错是最主要的。这样在图片中出现较多的蓝色背景情况下识别率会下降,不能有效提取车牌区域。对此本文提出了自适应调节方案。对分割出来的区域进行识别调整。根据长宽比,蓝白色比对候选区域进行多次定位。最终找到车牌区域。

     

    车牌倾斜校正

    在车牌识别系统中,车牌字符能够正确分割的前提是车牌图像能够水平,以至于水平投影和垂直投影能够正常进行。如果车牌倾斜没有矫正,那么水平投影和垂直投影,甚至铆钉都无法正常处理。车牌矫正是车牌定位和字符分割的一个重要处理过程。经过车牌定位后所获取的车牌图像不可避免地存在某种程度的倾斜,这种倾斜不仅会给下一步字符分割带来困难,最终也将对车牌的识别的正确率造成直接的影响。所以,当车辆信息中获取车牌的第一步,应该是检查倾斜角度,做倾斜矫正。本小节主要介绍车牌图像校正的算法MATLAB。

    车牌矫正算法有几种,主要是Hough变换法、Radon变换法。下面主要介绍Radon变换法

    图像投影,就是说将图像在某一方向上做线性积分(或理解为累加求和)。如果将图像看成二维函数f(x, y),则其投影就是在特定方向上的线性积分,比如f(x, y)在垂直方向上的线性积分就是其在x轴上的投影;f(x, y)在水平方向上的线积分就是其在y轴上的投影。通过这些投影,可以获取图像在指定方向上的突出特性,这在图像模式识别等处理中可能会用到。

    Radon变换(拉东变换),就是将数字图像矩阵在某一指定角度射线方向上做投影变换。这就是说可以沿着任意角度theta来做Radon变换。

    字符分割

    在汽车牌照自动识别过程中,字符分割有承前启后的作用。它在前期牌照定位的基础上进行字符的分割,然后再利用分割的结果进行字符识别。

    字符分割一般采用垂直投影法。由于字符在垂直方向上的投影必然在字符间或字符内的间隙处取得局部最小值的附近,并且这个位置应满足牌照的字符书写格式、字符、尺寸限制和一些其他条件。利用垂直投影法对复杂环境下的汽车图像中的字符分割有较好的效果。

    具体算法如下:

    1,确定图像中字符的大致高度范围:先自下而上对图像进行逐行扫描,直到遇到第一个黑素像素,记下行号,然后自上而下对图像进行逐行扫描,直到遇到第一个黑素像素,记下行号。这两个行号就标志出了字符大致的高度范围。

    2,确定每个字符的左起始和右终止位置:在第一步得到的高度范围内进行自左向右逐列扫描,遇到第一个黑色像素时,认为是字符分割的起始位,然后继续扫描,直到遇到有一列中没有黑色像素,认为是这个字符的右终止位置,准备开始进行下一个字符的分割。按照上述方法继续扫描,直到扫描到图像的最右端。这样就得到了每个字符的比较精确的快读范围。

    3,在已知的每个字符比较精确的宽度范围内,再按照第一步的方法,分别自下而上和自上而下,逐行扫描,来获取每个字符精确的高度范围。

    分割车牌字符左右边界时,通过垂直扫描过程,由于数字和字母具有连通性,所以分割数字和字母比较容易。通过垂直扫描过程,统计黑色像素点的个数,由于两个字符之间没有黑像素,所以可以作为字符分割的界限。

    字符归一化

    由于图像采集时图像的像素值不一样,经切割出来的字符的大小也不会不一样,所以在进行匹配前必须先进行字符图像归一化。使图像大小跟模板图像大小一致,Matlab提供一个改变图像大小的函数imresize,这里我便不打算多余介绍关于使用imresize一些命令。

    字符识别

    在前文,我就讲过字符识别的方法,神经网络算法和模板匹配算法,本系统采用的是模板匹配算法,下面主要详细介绍模板匹配算法。

    模板匹配:将从待识别的图像或图像区域中提取的若干特征量与模板相应的特征量逐个进行比较,计算它们之间规格化的互相关量,其中互相关量最大的一个就表示期间相似程度最高,可将图像归于相应的类。

    匹配时相似度函数定义为:

     

    其中, 为待识别车牌字符图像中像素点的灰度值,这里的取值为 0或1,为模板字符图像中像素点的灰度值,这里的取值为0或1;M 和N为模板字符点阵横向和纵向包含的像素个数。

    匹配的步骤为:

    (1)依次取出模板字符,将模板字符按照上、下、左、右四个方向,在周围五个像素的范围内滑动,每次分别计算出相似度S值,取其中S的最大值作为字符与模板字符之间的相似度函数。

    (2)依次从待识别的字符与模板字符的相似度中找出最大相似度所对应的模板字符,判断是否大于该字符的阈值T,如果S大于T,那么待识别的字符的匹配结果就是该模板字符,反之,如果S小于T,表示不匹配,则需要重新检测。

     

    车牌识别仿真

    采用车牌号渝F3W970的车牌照片进行仿真,仿真效果如下:

    图11 车牌原始图像

    使用车牌颜色特征的定位方法处理车辆图像,得到的车牌牌照提取图,效果如图12所示。

    图12车牌定位

    使用radon变换法处理车辆牌照,得到的车牌倾斜校正,效果如图13所示。

    图13 车牌倾斜校正

    使用最大类间方差法进行车辆图像二值化,效果如图13所示。

    图13 车牌二值化

     

    经过一系列的形态学操作,边框处理等等,效果如图14所示。

    图14 边框处理

     

    采用垂直投影法,车牌分割图像,效果如图15所示。

    图15 车牌分割

     

    经过模板匹配算法,效果如图16所示。

                                                               

    代码另上传了

    链接https://download.csdn.net/download/qq_17287777/10452721

     

     

    展开全文
  • 深度学习之目标检测与目标识别

    万次阅读 多人点赞 2018-06-05 21:58:54
    本文主要讲述了目标识别中的第一种类型---基于region proposal的目标检测和目标识别的算法, 主要主要包括R-CNN,Fast R-CNN,Faster R-CNN等网络, 揭示了基于region proposal的目标检测和目标识别的算法的发展历程....

    一 目标识别分类及应用场景

        目前可以将现有的基于深度学习的目标检测与识别算法大致分为以下三大类: 

        ① 基于区域建议的目标检测与识别算法,如R-CNN, Fast-R-CNN, Faster-R-CNN;

        ② 基于回归的目标检测与识别算法,如YOLO, SSD;

        ③ 基于搜索的目标检测与识别算法,如基于视觉注意的AttentionNet,基于强化学习的算法.

        目前, 目标识别主要有以下几个应用场景:

        ① 安全领域指纹识别人脸识别等,代表项目如Face++、依图科技、深醒科技等。

        ② 军事领域地形勘察飞行物识别等,代表项目全悉科技。

        ③ 交通领域车牌号识别无人驾驶交通标志识别等,代表项目纵目科技、TuSimple(图森科技)、驭势科技等。

        ④ 医疗领域心电图B超健康管理营养学等,代表项目智影医疗、图玛深维等。

        ⑤ 生活领域智能家居购物智能测肤等,代表项目Yi+、木薯科技、肌秘等。

        具体可参考这里:从图像识别多样化的应用场景,看计算机视觉的未来价值

    二 基于区域建议的目标识别的算法

    1. R-CNN

    1.1 基本工作流程:

        1) 接收一个图像, 使用Selective Search选择大约2000个从上到下的类无关的候选区域(proposal)

        2) 将提取出来的候选区域转换为统一大小的图片(拉升/压缩等方法), 使用CNN模型提取每一个候选区域的固定长度的特征.

        3) 使用特定类别的线性SVM分类器对每一个候选区域进行分类.

        4) Bounding Box回归.

    1.2 训练 (使用AlexNet, 要求输入为227*227大小的图像)

        1) 预训练预训练CNN(边界框标签不可用于该数据).

        2) 特征领域的微调使用基于CNN的SGD的训练,对模型进行微调.在这里选择学习率为预训练的1/10, 保证微调不破坏初始化.

        3) 将所有候选区域与真实框重叠(IoU)大于等于0.5的作为该框类的正例,其余的作为负例.再进行SVM分类.

            ------这个表明了训练过程是需要Grounding Truth(标定框)的, 是有监督的过程.

    注意: 在预训练和微调中使用的CNN网络参数的共享,并且提取的特征数目为(类别N+背景1)个.

    1.3 预测

        预测的过程和训练基本相同,不同的是:

        1) 预测的过程没有初始给定的标定框(Grounding Truth).

        2) Bounding Box回归.

        其实简单来说, 预测的过程就是根据在训练过程中找到的CNN回归值与所要预测的Grounding Truth之间的关系, 反向推导Grounding Truth的位置.

    1.4 R-CNN的优劣分析及小结

        1) R-CNN较之于传统方法的主要优势:

        ① 使用了Select Search进行proposal的选择, 极大地减少了proposal的数量.(百万级别~2000左右)

        ② 深度学习提取特征来代替人为设计, 较大地提高了精度和效率.

        ③ 使用了Bounding Box回归, 进一步提高了检测的精度.

        2) R-CNN的不足之处:

        ① 训练分为了多个步骤. 包括Select Search进行proposal的选择, CNN的模型训练(模型的预训练和微调), SVM的分类, Bounding Box回归等, 整个过程需要的时间过长.

        ② 由于当时的历史等各个因素的影响, 使用了SVM进行多类别分类,要训练多个分类器, 训练时间较长

        ③ 测试时间长,由于每张图片要处理大量的目标候选框

        3) 小结

        虽然R-CNN仍然存在很多的问题, 但是它打破了传统的目标识别的方式, 基于深度神经网络的目标识别技术也由此发展起来了.

    2. SPP Net

        为了后面介绍Fast R-CNN, 这里我们简要介绍下SPP Net的相关内容.


        SPP Net具有两个特点:

        ① 结合金字塔的思想, 实现了实现了CNNs的多尺寸输入. 解决了因为CNNs对输入的格式要求而进行的预处理(如crop,warp等)操作造成的数据信息的丢失问题.

        ② 只对原图进行一次卷积操作

    2.1 SPP Net的金字塔池化


        如上图所示, 输入图片经过多个卷积层操作, 再将输出的feature map输入到SPP Net池化层, 最后将池化后的特征输入全连接层.

        下面针对上图来说说SPP Net池化层的思想.可以参见这里.

        我们使用三层的金字塔池化层pooling,分别设置图片切分成多少块,论文中设置的分别是(1,4,16),然后按照层次对这个特征图feature A进行分别处理(用代码实现就是for(1,2,3层)),也就是在第一层对这个特征图feature A整个特征图进行池化(池化又分为:最大池化,平均池化,随机池化),论文中使用的是最大池化,得到1个特征。

        第二层先将这个特征图feature A切分为4个(20,30)的小的特征图,然后使用对应的大小的池化核对其进行池化得到4个特征,

        第三层先将这个特征图feature A切分为16个(10,15)的小的特征图,然后使用对应大小的池化核对其进行池化得到16个特征.

        最后将这1+4+16=21个特征输入到全连接层,进行权重计算. 当然了,这个层数是可以随意设定的,以及这个图片划分也是可以随意的,只要效果好同时最后能组合成我们需要的特征个数即可.

    2.2 SPP Net的一次卷积

        由于R-CNN先获取proposal,再进行resize,最后输入CNN卷积, 这样做效率很低. SPP Net针对这一缺点, 提出了只进行一次原图的卷积操, 得到feature map , 然后找到每一个proposal在feature map上对应的patch, 将这个patch作为每个proposal的卷积特征输入到SPP Net中,进行后续运算. 速度提升百倍.

    3. Fast R-CNN

        Fast R-CNN主要作用是实现了对R-CNN的加速, 它在R-CNN的基础上主要有以下几个方面的改进:

        ① 借鉴了SPP Net的思路, 提出了简化版的ROI池化层(没有使用金字塔), 同时加入了候选框映射的功能, 使得网络能够进行反向传播, 解决了SPP的整体网络训练的问题.

        ② 多任务Loss层. 1) 使用了softmax代替SVM进行多分类. 2) SmoothL1Loss取代了 Bounding Box回归.

    3.1  基本工作流程

        1) 接收一个图像, 使用Selective Search选择大约2000个从上到下的类无关的候选区域(proposal).

        2) 对整张图片进行卷积操作提取特征, 得到feature map.

        3) 找到每个候选框在feature map中的映射patch. 将patch作为每个候选框的特征输入到ROI池化层及后面的层.

        4) 将提取出的候选框的特征输入到softmax分类器中进行分类.==>替换了R-CNN的SVM分类.

        5) 使用SmoothL1Loss回归的方法对于候选框进一步调整位置.

    3.2 Fast R-CNN的优点及其不足之处

        1) 优点

        融合了R-CNN和SPP Net的精髓, 并且引入了多任务损失函数 ,极大地特高了算法的效率, 使得整个网络的训练和测试变得较为简单(相对R-CNN而言).

        2) 不足

        没有对Selective Search进行候选区域(region proposal)的选择进行改进, 仍然不能实现真正意义上的edge-to-edge(端到端)的训练测试.

    4. Faster R-CNN

        Faster R-CNN和Faste R-CNN的不同点主要是使用RPN网络进行region proposal的选择, 并且将RPN网络合并到CNN网络中, 真正地实现了端到端的目标检测.这也是 Faster R-CNN的里程碑式的贡献.

        Faster R-CNN的网络拓扑图如下图所示.

    4.1 基本工作流程

        1. 对整张图片输进CNN网络,得到feature map.

        2. 卷积特征输入到RPN,得到候选框的特征信息.

        3. 对候选框中提取出的特征,使用分类器判别是否属于一个特定类.

        4. 对于属于某一特征的候选框,用回归器进一步调整其位置.

    4.2 RPN

        用于提取region proposal的神经网络叫做Region Proposal Network(简称RPN).

        RPN网络的特点在于通过滑动窗口的方式实现候选框的提取,每个滑动窗口位置生成9个候选窗口(不同尺度、不同宽高), 提取对应9个候选窗口(anchor)的特征,用于目标分类和边框回归,与FastRCNN类似。目标分类只需要区分候选框内特征为前景或者背景。

        1) 候选框的选取依据:

        ① 对于IoU大于等于0.7的标记为前景样本, 低于0.3的样本标记为后景样本.

        ② 丢弃①中所有的边界样本

        对于每一个位置,通过两个全连接层(目标分类+边框回归)对每个候选框(anchor)进行判断,并且结合概率值进行舍弃(仅保留约300个anchor),没有显式地提取任何候选窗口,完全使用网络自身完成判断和修正。

        2) 损失函数

        同时使用两种损失函数:

        a. 分类的误差.

        b. 前景样本的窗口位置的偏差.

        3) 模型训练

        从模型训练的角度来看,通过使用共享特征交替训练的方式,达到接近实时的性能,交替训练方式描述为:

        1)根据现有网络初始化权值w,训练RPN;

        2)用RPN提取训练集上的候选区域,用候选区域训练FastRCNN,更新权值w;

        3)重复1、2,直到收敛.

    4.3 Faster R-CNN的优点及其不足之处

        1) 优点

        Faster R-CNN将我们一直以来的目标检测的几个过程(预选框生成, CNN特征提取, SVM/softmax/CNN预选框分类,y 预选框位置微调)完全被统一到同一个网络中去, 从真正意义上实现了从端到端的训练和测试.

        2) 不足

        预先获取预选区域,再对预选区域进行分类, 仍然具有较大的运算量, 还是没有实现真正意义上的实时检测的要求.

    三  小结

           本节介绍基于region proposal的目标检测与识别算法, 从最初的R-CNN, fast R-CNN,  直到最后的faster R-CNN, 逐步实现了端到端的目标识别和检测的网络.网络训练和测试的效率也有了一个较大的提升.可以说基于region proposal的R-CNN系列目标检测与识别算法是当前目标最主要的一个分支。

        下一章我们将讲述第二类--基于回归的目标检测与识别算法.

    展开全文
  • 视频目标检测识别

    万次阅读 多人点赞 2020-05-05 15:37:14
    之前文章目标检测API 已经介绍过API的基本使用,这里就不赘述了,直接上本次内容的代码了,添加的内容并不多。将测试的test.mp4原文件放到models-master\research\object_detection路径下,并创建一个detect_video....
  • 文字识别总结(OCR)

    万次阅读 2018-11-30 10:47:57
    最近在读Tesseract相关文章,发现一篇总结的不错的文章,对刚入门或者准备入门的具有挺大参考价值,转自:http://www.xtecher.com/Xfeature/view?aid=5372 链接可能挂掉了,今天重新补充一下...二 ,印刷体文字识别...
  • H5 图像识别

    千次阅读 2017-12-03 20:10:43
    识别对比1、百度识别发现百度的图片搜索识别率不是特别,下面为测试图片跟测试后的结果:测试图片:下面为测试后的结果:2、采用 tesseract.js 后结果H5 图像识别 (采用Tesseract.js 进行识别)简单的文案之类的,...
  • 一般应优先考虑能力检测,其次是怪癖检测,最后才是浏览器识别(因为基于用户代理检测,对用户代理字符串有很强的依赖性,而用户代理字符串由于其历史原因具有欺骗性)
  • 安卓实现扫一扫识别数字

    万次阅读 多人点赞 2018-04-25 14:53:18
    本文已授权微信公众号:鸿洋...首先实现识别数字等字符,我们要知道需要采用OCR (Optical Character Recognition,光学字符识别)来实现。而tesseract是非常不错的开源OCR工具,但是要在Android中直接...
  • 摘要:这篇博文介绍基于深度卷积神经网络实现的人脸表情识别系统,系统程序由Keras, OpenCv, PyQt5的库实现,训练测试集采用fer2013表情库。如图系统可通过摄像头获取实时画面并识别其中的人脸表情,也可以通过读取...
  • Matlab实现人脸识别

    万次阅读 多人点赞 2018-06-13 21:45:59
    最近在学习matlab图像处理部分,发现人脸识别这一块非常好玩,在这里做个总结。人脸识别之一:查找图片中的人脸并用方框圈出 这种类似于智能手机拍照时,屏幕里那个框任务头部的红框。大致步骤为:获取RGB图片---&...
  • 这是一篇含金量很高的干货文章,国家税务总局全国增值税发票查验平台验证码识别方案和具体思路,实验结果测试了200+次,识别率达到98%以上,识别速度的话,CPU大概5-8毫秒左右,模型大概3mb。
  • Java OCR 图像智能字符识别技术,可识别中文

    万次下载 热门讨论 2020-07-30 23:33:23
    Java OCR 图像智能字符识别技术,可识别中文。具体详见:http://blog.csdn.net/white__cat/article/details/38461449
  • OCR截图文字识别提取(无需安装)

    万次阅读 多人点赞 2020-04-06 22:34:42
    本软件无需安装, 适用于Windows 平台,具有截图,文字提取等功能,亦可用于图片和PDF中文字的识别提取中。目前版本为 V3.82。 截图文字提取 V3.82 下载地址如下 蓝奏云下载:https://www.lanzous.com/b679733 ...
  • 人脸微表情识别

    万次阅读 2020-02-23 23:58:50
    https://blog.csdn.net/think_three/article/details/80784952
  • 二、识别和消除循环依赖的方法 (一)使用JDepend识别循环依赖 (二)消除循环依赖的三大方法思考 三、案件实战分析 (一)具体案列介绍 (二)具体解决方案一:提取中介这 (三)具体解决方案二:...
  • 看完之后如有不懂,请看:关于人脸和指纹识别共同交流方案,也可以关注微信公众号:雄雄的小课堂,回复:人脸识别群获取群号,群内有直接可以运行的源码可供下载,人脸识别所需的软件群内也有!!! 人脸识别,...
  • 一、开发环境介绍Visual Studio 2015 Qt 5.6.3 (该版本及以上版本都可以) dlib-19.7 opencv-2.4.13.3-vc14 mkl_2018.0.124 (编译dlib时需要) ... Visual studio+Qt的开发环境搭建参考:Visual Stud
  • 图像识别技术原理和神经网络的图像识别技术

    千次阅读 多人点赞 2019-03-08 08:56:21
    图像识别技术是信息时代的一门...简单分析了图像识别技术的引入、其技术原理以及模式识别等,之后介绍了神经网络的图像识别技术和非线性降维的图像识别技术及图像识别技术的应用。从中可以总结出图像处理技术的应用...
1 2 3 4 5 ... 20
收藏数 1,639,043
精华内容 655,617
关键字:

识别