opencv_python答题卡自动判卷

2023-11-09

opencv_python答题卡自动判卷

  1. 设定答题卡模板
    该图像为答题卡的答题区域,黑色边框是为了能够在各种环境中轻易的检测,左部分和上部分的黑色矩形,是为能够定位到答题选项的坐标而设置,同时题目数量为20×3共60道选择题,在进行批改试卷之前,需要手动输入该次考试的正确答案作为模板来对识别的内容进行比较判分。
    在这里插入图片描述
  2. 读取答题卡图像并对图像进行灰度化处理
    在这里插入图片描述
# 最大值法求图像灰度值
def graying(image):
    h, w = image.shape[0], image.shape[1]
    gray = np.zeros((h, w), np.uint8)
    for i in range(h):
        for j in range(w):
            gray[i, j] = max(image[i,j][0], image[i,j][1], image[i,j][2])
    return gray

3 高斯模糊图像去噪点
在这里插入图片描述

gray = cv2.GaussianBlur(gray, (3, 3), 0)

4使用大津法二值分割图像
经过上一步操作后,答题卡的前背景分明,已经能够轻易将标识矩阵和答题区域涂改信息和背景分离开来,接下来需要将图像的标识矩阵和答题区域的涂改信息提取出来,需要进一步规划数字图像信息,二值化图像能使图像的数据量大大减少,既保留原有的数字信息,又能将无用的数据舍去,将原本数值范围为0-255的图像信息分割成像素值为0或255的二值图像,在这里0值代表背景,无用且不需要处理的信息,255表示目标信息(标识矩阵和答题区域的涂改信息),其算法原理非常简单,图像中像素值大于阈值时为255,小于阈值时为0。在二值化时,需要确定一个阈值,而这个阈值人为来定义是无法随着环境变换随时处于最优状态,在这里我们使用1979年由学者大津提出的对图像分割的高效算法来处理。大津法算法原理:
有假设如下:
u: 图像像素值平均值
g: 图像类间方差
w0: 图像背景像素点数占图像的比例
u0: 图像背景像素点的平均值
w1: 图像前景像素点数占图像的比例
u1: 图像前景像素点的平均值
算法公式为:
在这里插入图片描述
将第一个公式代入第二个得:
在这里插入图片描述
5使用开运算去噪点
此时已经得到较为完美的预处理图,但是不难发现,我们答题卡有一小块干扰像素。在实际情况中,这种干扰信息是有可能出现的,且大小与清晰度并没有固定范围,因此,在判卷之前,需要尽可能的将这种干扰信息去除,前面的各种图像预处理方法仅仅是将图像的前景和背景分离提取出定位标识信息和涂改信息,面对这样的情况,选择使用机器视觉中常用的开运算方法处理图像可以得到较好的效果。
在这里插入图片描述
开运算:先对图像进行腐蚀操作,再进行膨胀操作,就是开运算操作,能够消除细小的物体,将两个物体的细小的连接处去除从而分离两个物体,且拥有平滑边界的效果,被广泛应用于去除图像噪声。
腐蚀算法原理:
步骤1:定义一个卷积核B,卷积核可以是随意的大小与形状,但通常是带参考点的正方形或圆形,作为腐蚀的模板。
步骤2:将卷积核与原图像进行卷积操作,计算原图像包裹卷积核B的区域的像素最小值,这个区域则作为腐蚀操作后的结果。
例如有原图像A,卷积核B
在这里插入图片描述
则经过腐蚀算法操作之后可得实验结果为如下:
在这里插入图片描述
实验发现,右上角的小块图像噪声被腐蚀掉了,同时,下方的像素块被腐蚀了一圈且两块被分割开来,为了尽量减少图像的信息被过度腐蚀掉,接下来一步需要使用膨胀算法,将图像像素膨胀回来,尽可能去掉图像噪声的同时,也减少图像信息的过度减少。
膨胀算法原理:
步骤1:定义一个卷积核B,开运算时直接使用腐蚀操作时使用的卷积核B。
步骤2:将卷积核B与原图像进行卷积操作,计算原图像包裹卷积核B的区域的像素最大值,这个区域则作为膨胀操作后的结果。使用腐蚀操作后的结果来进行膨胀操作,实验效果如下:
在这里插入图片描述
观察开运算操作的前后对比,可以得知,右上角的噪声完全去除的同时,与原图像信息相比较,仅仅有五个像素点被去除,是完全可以接受的。
开运算操作实际实验效果如下:
在这里插入图片描述
步骤进行到这,发现右下角那块较大的图像噪声,仍旧无法消除,主要原因是该噪声较大,形状大小与颜色深度与目标信息相似,在准确保留目标信息的情况下难以将其分割开来,因此接下来选择通过定位图像信息来排除该图像噪声,对其不进行操作。
代码网上找的,忘记从哪抄的了,百度一下都有。。。

# 图像腐蚀
def etch(img, size):
    h=img.shape[0]
    w=img.shape[1]
    img1=np.zeros((h,w),np.uint8)
    for i in range (1,h-1):
        for j in range (1,w-1):
            min=img[i,j]
            for k in range (i-size,i+size):
                for l in range (j-size,j+size):
                    if k<0|k>=h-1|l<0|l>=w-1:
                        continue
                    if img[k,l]<min:
                        min=img[k,l]
            img1[i,j]=min
    return img1
# 图像膨胀
def expand(img, size):
    h=img.shape[0]
    w=img.shape[1]
    img1=np.zeros((h,w),np.uint8)
    for i in range (1,h-1):
        for j in range (1,w-1):
            max=img[i,j]
            for k in range (i-size,i+size):
                for l in range (j-size,j+size):
                    if k<0|k>=h-1|l<0|l>=w-1:
                        continue
                    if img[k,l]>max:
                       max=img[k,l]
            img1[i,j]=max
    return img1
# 开运算
def opening(image, size):
    etch_img = etch(image, size)
    expand_img = expand(etch_img, size)
    return expand_img

6使用canny边缘检测算法
canny边缘检测算法是一种运用非常广泛的算法,由john F.Canny在1986年提出的,一种多阶段的算法:
步骤1:对图像进行去噪
步骤2:计算图像的强度梯度
步骤3:在边缘上进行非极大值抑制
步骤4:对检测得到的边缘使用双阈值排查
步骤5:分析边缘之间的连接
通过这一系列的操作后便可得到图像内容里的边缘信息,我们前面已经对图像进行了深度的去噪操作,已经将大部分噪音完全清除,接下来的操作应该是区分定位区域和判卷区域的坐标,来对其进行判断处理,这一步只是为了观察图像的边缘信息,属于测试步骤,在实际的运用中,并不会使用该步骤来处理图像。
实验结果如下:
在这里插入图片描述
7筛选答题区域轮廓,透视变换矫正目标区域
通过轮廓检测可以计算多边形的外界,在这里我们需要检测出答题卡涂改区域的黑色边框位置,定位得到边框的四个顶点坐标,再对目标进行透视矫正操作。到这一步骤,已经得到矫正后的答题区域,接下来需要对图像的答题区域进行定位判断。
具体实验效果如下:
在这里插入图片描述

# 透视变换
from imutils.perspective import four_point_transform
def wPs(image, points):
    warped = four_point_transform(image, points)
    return warped

在这里插入图片描述
最后判断黑色集中的地方就可以判断选项了
在这里插入图片描述

使用摄像头实时判卷部分

调用摄像头部分的处理方式是对图像处理里使用的方法的一个总和。最终该系统的实时判卷,准确率达到百分之百,并且是在环境较差的的情况下进行判卷。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

全部代码如下

import cv2
import numpy as np
# 选取区域去除边缘
dist = 5
# 画图线粗度
line_w = 2
# 画笔颜色
red = (0, 0, 255)
green = (0, 255, 0)
blue = (255, 0, 0)
# 高斯模糊算法
#防止颜色值超出颜色取值范围(0-255)
# 开运算,先腐蚀,后膨胀
# 图像腐蚀
def etch(img, size):
    h=img.shape[0]
    w=img.shape[1]
    img1=np.zeros((h,w),np.uint8)
    for i in range (1,h-1):
        for j in range (1,w-1):
            min=img[i,j]
            for k in range (i-size,i+size):
                for l in range (j-size,j+size):
                    if k<0|k>=h-1|l<0|l>=w-1:
                        continue
                    if img[k,l]<min:
                        min=img[k,l]
            img1[i,j]=min
    return img1
# 图像膨胀
def expand(img, size):
    h=img.shape[0]
    w=img.shape[1]
    img1=np.zeros((h,w),np.uint8)
    for i in range (1,h-1):
        for j in range (1,w-1):
            max=img[i,j]
            for k in range (i-size,i+size):
                for l in range (j-size,j+size):
                    if k<0|k>=h-1|l<0|l>=w-1:
                        continue
                    if img[k,l]>max:
                       max=img[k,l]
            img1[i,j]=max
    return img1
# 开运算
def opening(image, size):
    etch_img = etch(image, size)
    expand_img = expand(etch_img, size)
    return expand_img
# 最大值法求图像灰度值
def graying(image):
    h, w = image.shape[0], image.shape[1]
    gray = np.zeros((h, w), np.uint8)
    for i in range(h):
        for j in range(w):
            gray[i, j] = max(image[i,j][0], image[i,j][1], image[i,j][2])
    return gray
# OTSU
# 二值化
def otsu(img):
    h=img.shape[0]
    w=img.shape[1]
    m=h*w
    otsuimg=np.zeros((h,w),np.uint8)
    threshold_max=threshold=0
    histogram=np.zeros(256,np.int32)
    probability=np.zeros(256,np.float32)
    for i in range(h):
        for j in range(w):
            s=img[i,j]
            histogram[s]+=1
    for k in range(256):
        probability[k]=histogram[k]/m
    for i in range(255):
        w0 = w1 = 0
        fgs = bgs = 0
        for j in range (256):
            if j<=i:
                w0+=probability[j]
                fgs+=j*probability[j]
            else:
                w1+=probability[j]
                bgs+=j*probability[j]
        u0=fgs/w0
        u1=bgs/w1
        g=w0*w1*(u0-u1)**2
        if g>=threshold_max:
            threshold_max=g
            threshold=i
    for i in range (h):
        for j in range (w):
            if img[i,j]<threshold:
                otsuimg[i,j]=255
            else:
                otsuimg[i,j]=0
    return otsuimg
# 透视变换
from imutils.perspective import four_point_transform
def wPs(image, points):
    warped = four_point_transform(image, points)
    return warped
# 轮廓检测函数
def find_contour(image):
    contours = cv2.findContours(image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[0]
    return contours
# 冒泡排序
def bubble_sort(lists, type):
    '''
    :param lists: 排序列表
    :param type: 排序类型
    :return: 排序结果
    '''
    count = len(lists)
    for i in range(0, count):
        xi, yi = cv2.boundingRect(lists[i])[0], cv2.boundingRect(lists[i])[1]
        for j in range(i + 1, count):
            xj, yj = cv2.boundingRect(lists[j])[0], cv2.boundingRect(lists[j])[1]
            if type == "title":
                if yi > yj:
                    lists[i], lists[j] = lists[j], lists[i]
            elif type == "answer":
                if xi > xj:
                    lists[i], lists[j] = lists[j], lists[i]
            else:
                return print("排序出错")
    return lists
#统计结果
def count(roi):
    '''
    :param roi: 答题选项区域
    :return: 选择结果
    '''
    grade = 0
    long = roi.shape[1] / 8
    contour = find_contour(roi)
    if len(contour) == 0:
        return 0
    elif len(contour) >= 2:
        return -2
    for c in contour:
        perimeter = cv2.arcLength(c, True)
        if perimeter > 5:
            x = cv2.boundingRect(c)[0]
            if x < long:
                grade = 1
            elif x < long*3:
                grade = 2
            elif x < long*5:
                grade = 3
            else:
                grade = 4
    return grade
# 轮廓检测处理
def contours(img, dst):
    '''
    :param img: 查看效果图像
    :param dst: 轮廓检测对象
    :return: 效果图像,轮廓检测效果图像,检测结果
    '''
    img_dst = img.copy()
    edged = cv2.Canny(dst, 10, 100)
    img_cnts = find_contour(edged)
    # 如果未检测到轮廓则退出
    c_len = len(img_cnts)
    if c_len == 0:
        print("error:No find contours!")
        return img, dst
    # 画出所有轮廓
    ## 得到答题区域
    pt = None
    for c in img_cnts:
        cv2.drawContours(img, [c], -1, red, line_w)
        perimeter = cv2.arcLength(c, True)
        if perimeter < 40:
            continue
        approx = cv2.approxPolyDP(c, 0.02*perimeter, True)
        if len(approx) == 4:
            pt = approx
        hull = cv2.convexHull(c)
        cv2.polylines(img, [hull], True, green, line_w)
    pt = pt.reshape(4,2)
    # 透视变换
    img_dst = wPs(img_dst, pt)
    dst = wPs(dst, pt)
    img_dst = img_dst[dist:img_dst.shape[0]-dist,dist:img_dst.shape[1]-dist]
    dst = dst[dist:dst.shape[0]-dist,dist:dst.shape[1]-dist]
    # 处理答题卡答题区域部分
    contours_roi = find_contour(dst)
    title, answer = [], []
    for c in contours_roi:
        x, y, w, h = cv2.boundingRect(c)
        if x >= dist and y <= dist:
            answer.append(c)
        if x < dist and y > dist:
            title.append(c)
    # 冒泡排序
    title = bubble_sort(title, "title")
    answer = bubble_sort(answer, "answer")
    # 判卷
    result = np.zeros(60, dtype=np.int8)
    for title_number in range(60):
        miny = cv2.boundingRect(title[title_number%20])[1]
        x, y, w, h = cv2.boundingRect(answer[int(title_number/20+1)*4-1])
        x1= cv2.boundingRect(answer[int(title_number/20+1)*4-4])[0]
        maxx, maxy = x+w, miny+h
        cv2.rectangle(img_dst, (x1, miny), (maxx, maxy), blue, line_w)
        roi = dst[miny:maxy, x1:maxx]
        grade = count(roi)
        result[title_number] = grade
        print("title"+str(title_number+1)+":",grade)
    return img, img_dst, result
def new_contours(img_dst, aim_otsu):
    '''
    :param img_dst: 查看效果图像
    :param aim_otsu: 答题卡区域
    :return: 效果图像, 识别结果
    '''
    # 处理答题卡答题区域部分
    contours_roi = find_contour(aim_otsu)
    title, answer = [], []
    for c in contours_roi:
        x, y, w, h = cv2.boundingRect(c)
        if x >= dist and y <= dist:
            answer.append(c)
        if x < dist and y > dist:
            title.append(c)
    # 冒泡排序
    title = bubble_sort(title, "title")
    answer = bubble_sort(answer, "answer")
    # 判卷
    result = np.zeros(60, dtype=np.int8)
    for title_number in range(60):
        miny = cv2.boundingRect(title[title_number % 20])[1]
        x, y, w, h = cv2.boundingRect(answer[int(title_number / 20 + 1) * 4 - 1])
        x1 = cv2.boundingRect(answer[int(title_number / 20 + 1) * 4 - 4])[0]
        maxx, maxy = x + w, miny + h
        cv2.rectangle(img_dst, (x1, miny), (maxx, maxy), blue, 1)
        roi = aim_otsu[miny:maxy, x1:maxx]
        grade = count(roi)
        result[title_number] = grade
    return img_dst, result
# 主要步骤
def run(img):
    '''
    :param img: 可操作的原图像
    :return: 预处理后的图像
    '''
    print("image.shape:", img.shape)
    # 最小值法求图像灰度值
    gray = graying(img)
    # 二值分割大津法
    thresh = otsu(gray)
    img_open = opening(thresh, 1)
    return img_open
from PIL import Image, ImageDraw, ImageFont
font_china = ImageFont.truetype('simhei.ttf', 40, encoding="utf-8")
def ChinaToImage(image, str, color):
    '''
    :param image: 原图像
    :param str: 需要写的字
    :param color:画笔颜色
    :return:写完字的图像
    '''
    img_PIL = Image.fromarray(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
    draw = ImageDraw.Draw(img_PIL)
    draw.text((20, 20), str, color,font=font_china)
    return cv2.cvtColor(np.asarray(img_PIL),cv2.COLOR_RGB2BGR)
# 提示是否可以开始函数
def hint(image, b):
    '''
    :param image: 摄像头画面
    :param b: 提示是否可以批卷
    :return: 返回写入提示的画面
    '''
    str_s = '按下Esc退出!\n按下空格开始!'
    str_e = '按下Esc退出!\n请调整好角度!'
    if b:
        image = ChinaToImage(image, str_s, green)
    else:
        image = ChinaToImage(image, str_e, red)
    return image
# 查找答题卡轮廓,提示是否可以开始
def star_bool(image):
    '''
    :param image: 摄像头画面
    :return: 是否可以开始批卷
    '''
    image_gray = graying(image)
    edged = cv2.Canny(image_gray, 10, 100)
    con = find_contour(edged)
    b = False
    points = None
    for c in con:
        cv2.drawContours(image, [c], -1, red, line_w)
        perimeter = cv2.arcLength(c, True)
        w, h = cv2.minAreaRect(c)[1]
        if w == 0 or h == 0 or w/h < 0.6:
            continue
        if perimeter < 200:
            continue
        approx = cv2.approxPolyDP(c, 0.02 * perimeter, True)
        if len(approx) != 4:
            continue
        b = True
        points = approx
        hull = cv2.convexHull(c)
        cv2.polylines(image, [hull], True, green, line_w)
    aim_c = None
    aim_otsu = None
    if b:
        try:
            points = points.reshape(4, 2)
            aim = wPs(image_gray, points)
            aim_c = wPs(image, points)
            aim = aim[dist:aim.shape[0] - dist, dist:aim.shape[1] - dist]
            aim_c = aim_c[dist:aim_c.shape[0] - dist, dist:aim_c.shape[1] - dist]
            aim_otsu = otsu(aim)
            cv2.imshow('aim_otsu', aim_otsu)
        except:
            print('角度误差大!')
    return b, aim_c, aim_otsu
# 批改函数
def correct(model_answer, result):
    '''
    :param model_answer: 该试卷正确答案
    :param result: 识别答案
    :return: 显示批卷结果,显示效果,可检测对象
    '''
    if len(model_answer) != 60:
        print('答案模板数量不对!\n请重新设置答案。')
        return 0
    # 成绩
    grade = {'score':0, 'no choice':0, 'mul':0}
    no_choice_number = []
    mul_number = []
    # 题的分值,topik考试基本每题两分
    cube = 2
    # 计算分数
    for index in range(len(model_answer)):
        if model_answer[index] > 4 or model_answer[index] < 1:
            print("答案模板有误!\n请重新设置答案。")
            return 0
        if result[index] == 0:
            no_choice_number.append(index+1)
            grade['no choice'] += 1
            continue
        if result[index] == -2:
            mul_number.append(index+1)
            grade['mul'] += 1
            continue
        if model_answer[index] == result[index]:
            grade['score'] += cube
    # 批卷完成
    print('-' * 70)
    print('-' * 70)
    print('正确答案:\n', model_answer)
    print('识别结果:\n', result)
    print('-'*35)
    print('分值:', grade['score'])
    print('-' * 35)
    print('空选数量:', grade['no choice'])
    print('空选题号:\n', no_choice_number)
    print('-' * 35)
    print('多选数量:', grade['mul'])
    print('多选题号:\n', mul_number)
    print('-' * 70)
    print('-' * 70)
def main():
    # 该变量为本次试卷正确答案模板,需要根据试卷受到修改原本正确答案
    model_answer = [1, 2, 3, 4,
                    1, 2, 3, 4,
                    1, 2, 3, 4,
                    1, 2, 3, 4,
                    1, 2, 3, 4,
                    1, 2, 3, 4,
                    1, 2, 3, 4,
                    1, 2, 3, 4,
                    1, 2, 3, 4,
                    1, 2, 3, 4,
                    1, 2, 3, 4,
                    1, 2, 3, 4,
                    1, 2, 3, 4,
                    1, 2, 3, 4,
                    1, 2, 3, 4,]
    cap = cv2.VideoCapture(0)
    cv2.namedWindow("image", 0)
    cv2.resizeWindow("image", 640, 480)
    while True:
        sucess, img = cap.read()
        img_temp = img.copy()
        b, aim, aim_otsu = star_bool(img_temp)
        img_temp = hint(img_temp, b)
        cv2.imshow("image", img_temp)
        k = cv2.waitKey(16)
        # Esc结束
        if k == 27:
            break
        # 空格按下开始
        elif k == 32:
            try:
                img_dst, result = new_contours(aim, aim_otsu)
                correct(model_answer, result)
                cv2.imshow('answer_roi', img_dst)
            except:
                print("您拍答题卡的角度误差过大")
            else:
                if cv2.waitKey(0) == 27:
                    break
                else:
                    continue
    cap.release()
    cv2.destroyAllWindows()
if __name__=="__main__":
    main()

感谢各位大爷~

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

opencv_python答题卡自动判卷 的相关文章

  • 在OpenCV Python中编写4通道以上图像

    这对我来说是一个持续的挑战 我正在尝试使用 openCV 将两个 3 RGB 图像组合成一个 6 通道 TIFF 图像 到目前为止我的代码如下 import cv2 import numpy as np im1 cv2 imread im1
  • 变形:Opencv 使用 Visual Studio 将图像显示到曲面屏幕

    我正在尝试使用 opencv API 来扭曲图像 以便将其显示到曲面屏幕上 我已经浏览了opencv中提供的翘曲apihere http docs opencv org 2 4 modules stitching doc warpers h
  • 在 python + openCV 中使用网络摄像头的问题

    我正在使用以下代码使用 openCV python 访问我的网络摄像头 import cv cv NamedWindow webcam feed cv CV WINDOW AUTOSIZE cam cv CaptureFromCAM 1 然
  • 使用 Azure 机器学习检测图像中的符号

    4年前我发帖这个问题 https stackoverflow com q 6999920 411094不幸的是 得到的一些答案超出了我的技能水平 我刚刚参加了一次构建巡演会议 他们在会上谈论了机器学习 这让我想到了使用 ML 来解决我的问题
  • 附加信息:OpenCV:使用 c# 的不同大小的对象

    目前 我的 EmguCV c 代码面临问题 我试图从数据库中识别我的图像 但它不起作用 一旦检测到我的脸 它就会崩溃 然后会出现此错误 附加信息 OpenCV 不同大小的对象 我尝试寻找这个错误 但我一无所知 这是我的代码 Action f
  • 从单应性估计 R/T

    我一直在尝试计算 2 个图像中的特征 然后将这些特征传递回CameraParams R没有运气 特征已成功计算并匹配 但是问题是将它们传递回R t 我明白你必须分解Homography为了使这一点成为可能 我已经使用如下方法完成了 http
  • Pyinstaller“无法执行脚本 pyi_rth_pkgres”并且缺少软件包

    这是我第一次在这里发布问题 因为我的大部分问题已经被其他人回答了 我正在 python 中开发 GUI 应用程序 并尝试使用 pyinstaller 将其打包到单个文件夹和 exe 中 以便于移植 目前 我使用 Windows 10 和 a
  • 如何计算立体视觉的基本矩阵

    我正在尝试编写一些代码来计算基本矩阵以确定立体图像之间的关系 我从大多数人推荐的 Hartley 和 Zisserman 书开始 但它没有任何实际示例 并且示例代码是在 MATLAB 中 而我没有 然后我切换到这个比较实用 里面有实际例子
  • 如何使用 SimpleBlobDetector 获取 blob 的额外信息?

    robot sherrick 回答了我这个问题 https stackoverflow com a 13534094 1705967 这是他回答的后续问题 cv SimpleBlobDetectorOpencv 2 4 中的 看起来非常令人
  • 如何将图像从 np.uint16 转换为 np.uint8?

    我正在创建一个图像 image np empty shape height width 1 dtype np uint16 之后我将图像转换为 BGR 模型 image cv2 cvtColor image cv2 COLOR GRAY2B
  • 有人曾经在 MacOS 10.6 上使用过 OpenCV 和 Python 2.7 吗?

    在过去的 6 个月里 我一直断断续续地尝试让 OpenCV 在 MacOS 上与 Python 配合使用 每次有新版本发布时 我都会再次尝试并失败 我已经尝试过 64 位和 32 位 并且 xcode gcc 和 gcc 都是通过 macp
  • 在 Android 中使用 OpenCV 查找图像匹配

    我正在尝试构建一个 Android 应用程序 该应用程序可以比较设备相机拍摄的照片 以在一组图像中找到匹配项 我已经在 Android Studio 上配置了 OpenCV 但仅此而已 有人可以通过链接到资源或建议教程来提供帮助吗 Open
  • OpenCV Android - 无法解析相应的JNI函数

    我正在尝试按照此处概述的本教程使用 Opencv 设置 Android Studio https www youtube com watch v OTw GIQNbD8 https www youtube com watch v OTw G
  • 使用 OpenCV VideoWriter 将 RTSP 流存储为视频文件

    我正在使用 OpenCV 开发一个 Python 模块 该模块连接到 RTSP 流以对视频执行一些预处理 主要是降低 fps 和分辨率 然后将其存储在文件系统中 但是 即使在尝试了几种编解码器 寻找类似的开发之后 我总是得到一个空的视频 我
  • 如何在 OpenCV 中将 Float Mat 写入文件

    我有一个矩阵 Mat B 480 640 CV 32FC1 包含浮点值 我想将此矩阵写入一个可以打开的文件Notepad https en wikipedia org wiki Windows Notepad or 微软Word https
  • VideoCapture 未检测到 uEye 摄像头

    我的 uEye 相机遇到了一个问题 使用我的笔记本电脑摄像头 id 0 或 USB 上的网络摄像头 id 1 此行完美运行 TheVideoCapturer open 1 TheVideoCapturer 属于 VideoCapture 类
  • 使用 OpenCV 和 Python 叠加两个图像而不丢失颜色强度

    如何叠加两个图像而不损失两个图像的颜色强度 我有图像1和图像2 2 我尝试使用 0 5 alpha 和 beta 但它给我的合并图像的颜色强度只有一半 dst cv2 addWeighted img1 0 5 img2 0 5 0 但是当我
  • OpenCV 读取视频文件时内存不足

    此示例从文件中读取视频cv2 VideoCapture在 python OpenCV 中内存不足 import cv2 cap cv2 VideoCapture file mp4 while True ret frame cap read
  • Python 中的 Lanczos 插值与 2D 图像

    我尝试重新缩放 2D 图像 灰度 图像大小为 256x256 所需输出为 224x224 像素值范围从 0 到 1300 我尝试了两种使用 Lanczos 插值来重新调整它们的方法 首先使用PIL图像 import numpy as np
  • OpenCV Python cv2.mixChannels()

    我试图将其从 C 转换为 Python 但它给出了不同的色调结果 In C Transform it to HSV cvtColor src hsv CV BGR2HSV Use only the Hue value hue create

随机推荐

  • 短信验证码

    短信验证码用的是阿里云的 目录结构如下 其中aliyunsdkdysmsapi是在官方下载的 https help aliyun com document detail 55359 html aliyun py coding utf 8 i
  • 注入技术--LSP劫持注入

    1 原理 简单来说 LSP就是一个dll程序 应用程序通过winsock2进行网络通信时 会调用ws2 32 dll的导出函数 如connect accept等 而后端通过LSP实现这些函数的底层 简单来说就是调用winsock2提供的函数
  • 硬件系统工程师宝典(13)-----PCB的布局“有讲究”

    各位同学大家好 欢迎继续做客电子工程学习圈 今天我们继续来讲这本书 硬件系统工程师宝典 上篇我们说到EMC的标准以及提高EMC性能的一些常用方法 今天我们来看看PCB上模块的布局有什么讲究 模块划分及布局 PCB上模块的划分和布局会影响到布
  • Linux  root密码忘记了,怎么办?

    Linux root用户密码忘记了 怎么办 一 清除密码 首先 启动Linux 出现这个画面 有的版本不一定 和这个 一样但是大同小异 注意这句话就行 Press any key to enter the menu 按任意键进入菜单 然后
  • Cocos2d-x Js Binding 的手动绑定实现

    http www ityran com archives 4902 Cocos2d x Js Binding 的手动绑定实现 一叶 cocos2d x 08 13 2304 4条评论 随着 Cocos2d x 的发展 Cocos2d htm
  • Command ‘roscore‘ not found, but can be installed with: sudo apt install python-roslaunch

    ubuntu18 04安装ros melodic时报错 解决方法 查看是否安装包 cd opt ros melodic bin ls 发现没有roscore 安装 在bin目录 sudo apt get install ros melodi
  • NGINX指定启动的配置文件

    若不指定安装路径 nginx默认安装在 usr local nginx路径下 若不指定nginx的配置文件 nginx默认启动找的是同级nginx更路径下的 conf nginx conf配置文件 但该配置文件的所在路径 以及文件名不是绝对
  • git revert后无法merge发生的惨案

    git revert后无法merge发生的惨案 前景描述 目前公司开发模式是这样的 有测试分支test 开发分支dev1 dev2 dev3 dev1 dev2 dev3都是基于test分支拉出来的 各分支如果没有问题后都会合并到test
  • c# postgresql帮助类

    1 安装Npgsql 2 代码
  • 判断Java中map键值对中是否包含一个key

    boolean b map containsKey menuId
  • 前端拼音首字母搜索姓名

    前言 实际工作中碰到一个业务场景 只需要输入姓名字母简称就可以直接匹配出相应的汉字 这样可以极大的方便用户检索 提升用户的使用体验 具体需求 在搜索框中根据拼音首字母来快速搜索出人名 例如曾琴琴 曾是多音字 可以通过输入 z c zq cq
  • socket通讯相互发送读取xml实例

    首先了解下socket通讯传输数据的特点 数据在网络传输时使用的都是字节流或字符流 Socket也不例外 所以我们发送数据的时候需要转换为字节发送 读取的时候也是以字节为单位读取 那么问题就在于socket通讯时 接收方并不知道此次数据有多
  • git 某次提交补丁的生成与应用

    使用git format patch生成所需要的patch git format patch s 1bbe3c8c197a35f79bfddaba099270a2e54ea9c7 please replace the hash code w
  • 协议栈中绑定流程的一点认识

    2011年4月27日 初学者关于协议栈中绑定流程的一点认识 本人刚接触zigbee不久 在学习中将不断记录每天的进步 期待大家的指导 在这里指出我还是参考了ZStack CC2530 2 3 1 1 4 0 Projects zstack
  • Motion Detection

    Frame Difference Method FDM Background Subtraction Method BSM B is background image Adaptive Background Substraction Met
  • 在Windows上编译 CEF3 且加入mp3/mp4的支持

    现在因为工作需要 为了得到支持mp3 mp4的cef32和64位版本 需要编译cef3 本次编译版本是3239 6 0 3239 132 一 编译条件 1 可用于稳定的下载网络 2 Win7或者更新的系统 必须64位 至少8GB的RAM 我
  • Android实现网络请求方法

    Android网络请求 1 安卓开发网络请求可谓是安卓开发的灵魂 如果你不会网络请求 那么你开发的应用软件就是一具没有灵魂的枯骨 在安卓开发中进行网络请求和java中的网络请求有异曲同工之妙 但是安卓软件毕竟的安装在我们手机上的 而平常的应
  • 快递运输【Java】

    快递运输 Java 题目描述 一辆运送快递的货车 运送的快递均放在大小不等的长方体快递盒中 为了能够装载更多的快递 同时不能让货车超载 需要计算最多能装多少个快递 快递的体积不受限制 快递数最多1000个 货车载重最大50000 输入描述
  • 白山头讲PV:calibre中如何extract net

    在进行lvs分析的时候 能够对net进行trace 具有非常重要的意义 本文详细介绍如何在calibre中对一条net进行trace并highlight 如何trace trace的操作非常简单 右击你要trace的net的一部分 shap
  • opencv_python答题卡自动判卷

    opencv python答题卡自动判卷 设定答题卡模板 该图像为答题卡的答题区域 黑色边框是为了能够在各种环境中轻易的检测 左部分和上部分的黑色矩形 是为能够定位到答题选项的坐标而设置 同时题目数量为20 3共60道选择题 在进行批改试卷