opencv联合python实例1 ——银行卡数字排序剪切提取,去除噪点,删除小面积,找出轮廓并画出轮廓,KNN目标跟踪

银行卡数字排序剪切提取

import cv2
import numpy as np

def cv_show(name,img):
    cv2.imshow(name,img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

src = cv2.imread("E:/ocr_a_reference.png",cv2.IMREAD_COLOR)
if src is None:
    print("could not load the picture...")
    exit()
cv_show("src",src)
gray = cv2.cvtColor(src,cv2.COLOR_BGR2GRAY)
if gray is None:
    print('could not translate to gray')
    exit()
cv_show('gray',gray)
thresh = cv2.threshold(gray,127,255,cv2.THRESH_BINARY_INV)[1]
if thresh is None:
    print('the thresh load is fail..')
    exit()
cv_show('thresh',thresh)
contours = cv2.findContours(thresh,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)[0]
if contours is None:
    print('The contours is Null...')
    exit()
dst = src.copy()
cv2.drawContours(dst,contours,-1,(0,255,0),2)
cv_show('dst',dst)
dst = cv2.cvtColor(dst,cv2.COLOR_BGR2GRAY)
loc = gray.copy()
#让轮廓从左到右开始排序
boundingBoxes = [cv2.boundingRect(c) for c in contours] #用一个最小的矩形,把找到的形状包起来x,y,h,w
(contours, boundingBoxes) = zip(*sorted(zip(contours, boundingBoxes),
                    key=lambda b: b[1]))
print(len(contours))
#显示轮廓
digi={}
for (i,c) in enumerate(contours):
    (x,y,w,h) = cv2.boundingRect(c)
    group = gray[y-5:y+h+5,x-5:x+w+5]
    roi = cv2.resize(group, (57, 88)) 
    print(roi.shape)
    cv_show("group",group)
    digi[i] = roi
print(len(digi))

去除噪点,删除小面积

import cv2
import numpy as np


image = cv2.imread("D:/2.jpg")
img = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(img,30,255,cv2.THRESH_BINARY)
contours= cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)[1]
src = image.copy()
src1 = image.copy()
for i in range(len(contours)):
	area = cv2.contourArea(contours[i])
	if area<100:
		continue
	cv2.drawContours(src,[contours[i]],-1,(255,0,0),2)
cv2.drawContours(src1,contours,-1,(0,255,0),2)
cv2.imshow("src",src)
cv2.imshow("src1",src1)

cv2.waitKey(0)
cv2.destroyAllWindows()

找出轮廓并画出轮廓

import cv2
import numpy as np


image = cv2.imread("D:/2.jpg")
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
ret,thresh =cv2.threshold(gray,50,255,cv2.THRESH_BINARY)
cv2.imshow("thresh",thresh)
binary,contours,hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
draw_img = image.copy()
res = cv2.drawContours(draw_img,contours,-1,(0,0,255),1)
cv2.imshow("res",res)
cv2.waitKey(0)
cv2.destroyAllWindows()

找出轮廓去除小面积

# -*- coding: utf-8 -*-
import cv2  
import numpy as np  

#打开USB摄像头
#camera=cv2.VideoCapture(0)  

#获得视频的格式  
camera= cv2.VideoCapture("111.mp4")  

#以下fps,size用不了
#获得码率及尺寸  
#fps = camera.get(cv2.CV_CAP_PROP_FPS)  
#size = (int(camera.get(cv2.CV_CAP_PROP_FRAME_WIDTH)), int(camera.get(cv2.CV_CAP_PROP_FRAME_HEIGHT)))  

#指定写视频的格式, I420-avi, MJPG-mp4  
#videoWriter = cv2.VideoWriter('oto_other.mp4', cv2.cv.CV_FOURCC('M', 'J', 'P', 'G'), fps, size)  

#设置窗口大小,缺省的过大
cv2.namedWindow("Video",0);
cv2.resizeWindow("Video", 800, 600);
cv2.namedWindow("BW-Video",0);
cv2.resizeWindow("BW-Video", 640, 480);
cv2.namedWindow("DI-Video",0);
cv2.resizeWindow("DI-Video", 640, 480);


firstframe=None

while (camera.isOpened()):  

    ret,frame = camera.read()
    #print ret, frame
    
    if not ret:  
        break
        
    gray=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)  
    gray=cv2.GaussianBlur(gray,(21,21),0)  
    
    if firstframe is None:  
        firstframe=gray  
        continue  
    
    #获得与背景的差值,背景很重要,最好是除了移动的主体之外,什么都不懂,且背景中没有移动的主体
    frameDelta = cv2.absdiff(firstframe,gray)  
    
    #获得黑白的图片
    thresh = cv2.threshold(frameDelta, 65, 255, cv2.THRESH_BINARY)[1]  
    thresh = cv2.dilate(thresh, None, iterations=2)  
    
    #获得移动物体的轮廓,注意opencv3.0以后,返回参数的位置不同,轮廓在第2位
    cnts, hierarchy, rr = cv2.findContours(thresh.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)  
    #print cnts
    
    #可以直接画出轮廓,但效果不如方框
    #cv2.drawContours(frame, hierarchy, -1, (0, 255, 0), 3)
 
    
    for c in hierarchy:
    
        # if the contour is too small, ignore it
        # 轮廓面积
        #area = cv2.contourArea(c)
        #print area
        # 周长,或者说,弧长;第二个参数的True表示该轮廓是否封闭
        #perimeter = cv2.arcLength(c,True)
        #sprint  perimeter
        
        if cv2.contourArea(c) <= 8000:
            continue
    
        # compute the bounding box for the contour, draw it on the frame,
        # and update the text
        
        # 计算轮廓的边界框,在当前帧中画出该框
        x,y,w,h = cv2.boundingRect(c)        
            
        #x,y,w,h=cv2.boundingRect(thresh)  
        frame=cv2.rectangle(frame,(x,y),(x+w,y+h),(0,0,255),3)  
        
        # 计算的最小轮廓
        #rect = cv2.minAreaRect(c)
        #print rect
    
    cv2.imshow(u"Video", frame)  
    cv2.imshow(u"BW-Video", thresh)  
    cv2.imshow(u"DI-Video", frameDelta)  
    key = cv2.waitKey(1)
     
    if key == ord("q"):  
        break  

camera.release()  
cv2.destroyAllWindows()  

import cv2 as cv
import numpy as np


src = cv.imread(r"D:\test5.jpg") # 读取图片
ROI = np.zeros(src.shape, np.uint8) # 创建与原图同尺寸的空numpy数组,用来保存ROI信息

gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY) # 灰度化
ret, binary = cv.threshold(gray,
			   0, 255, 
			   cv.THRESH_BINARY_INV | cv.THRESH_TRIANGLE) # 自适应二值化
			   
out_binary, contours, hierarchy = cv.findContours(binary, 
			   cv.RETR_EXTERNAL,
			   cv.CHAIN_APPROX_SIMPLE) # 查找所有轮廓,每个轮廓信息保存于contours数组中

for cnt in range(len(contours)): # 基于轮廓数量处理每个轮廓
    # 轮廓逼近,具体原理还需要深入研究
    epsilon = 0.01 * cv.arcLength(contours[cnt], True)
    approx = cv.approxPolyDP(contours[cnt], epsilon, True) # 保存逼近结果的顶点信息
    							   # 顶点个数决定轮廓形状 
    # 计算轮廓中心位置							   
    mm = cv.moments(contours[cnt])
    if mm['m00'] != 0:
        cx = int(mm['m10'] / mm['m00'])
        cy = int(mm['m01'] / mm['m00'])
        color = src[cy][cx]
        color_str = "(" + str(color[0]) + ", " + str(color[1]) + ", " + str(color[2]) + ")"
        p = cv.arcLength(contours[cnt], True)
        area = cv.contourArea(contours[cnt])
        
        # 分析几何形状
        corners = len(approx)
        if corners == 3 and (color[2]>=150 or color[0]>=150) and area>1000:  # 一系列判定条件是由该项目的特点所调整的
            cv.drawContours(ROI, contours, cnt, (255, 255, 255), -1)  # 在ROI空画布上画出轮廓,并填充白色(最后的参数为轮廓线条宽度,如果为负数则直接填充区域)
            imgroi = ROI & src  # ROI和原图进行与运算,筛出原图中的ROI区域
            cv.imshow("ROI", imgroi)
            cv.imwrite(r"D:\ROI.jpg")
            
        if corners >= 10 and (color[2]>=150 or color[0]>=150) and area>1000:          
    	    cv.drawContours(ROI, contours, cnt, (255, 255, 255), -1)
            imgroi = ROI & src
            cv.imshow("ROI",imgroi)
            cv.imwrite(r"D:\ROI.jpg")

            
cv.waitKey(0)
cv.destroyAllWindows() 

KNN跟踪(效果较好)

import numpy as np
import cv2

#cap = cv2.VideoCapture("E:/test.avi")



def detect_video(video):
    camera = cv2.VideoCapture(video)
    history = 500  # 训练帧数

    bs = cv2.createBackgroundSubtractorKNN(detectShadows=True)  # 背景减除器,设置阴影检测
    bs.setHistory(history)

    frames = 0

    while True:
        res, frame = camera.read()

        if not res:
            break

        fg_mask = bs.apply(frame)  # 获取 foreground mask

        if frames < history:
            frames += 1
            continue

        # 对原始帧进行膨胀去噪
        th = cv2.threshold(fg_mask.copy(), 244, 255, cv2.THRESH_BINARY)[1]
        th = cv2.erode(th, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3)), iterations=2)
        dilated = cv2.dilate(th, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (8, 3)), iterations=2)
        # 获取所有检测框
        image, contours, hier = cv2.findContours(dilated, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
        # print(len(contours))
        tempjs = 0
        for c in contours:
            # 获取矩形框边界坐标
            x, y, w, h = cv2.boundingRect(c)
            # 计算矩形框的面积
            area = cv2.contourArea(c)
            if 500 < area:
                cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
                tempjs = tempjs + 1

        print(tempjs)
        cv2.imshow("detection", frame)
        cv2.imshow("back", dilated)
        if cv2.waitKey(110) & 0xff == 27:
            break
    camera.release()


if __name__ == '__main__':
    # video = 'person.avi'
    detect_video("E:/test.avi")
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值