Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 量化一张幻灯片上写了多少字_Python_Python 3.x_Image Processing - Fatal编程技术网

Python 量化一张幻灯片上写了多少字

Python 量化一张幻灯片上写了多少字,python,python-3.x,image-processing,Python,Python 3.x,Image Processing,我有一个幻灯片视频,演示者在幻灯片上手写笔记: 我想创建一个程序,检测幻灯片是否由手写笔记填写,或者是否是新幻灯片 我想到的一种方法是文本的OCR,但这并不合适,因为这里唯一改变的文本不是手写的就是数学的 到目前为止我所做的: 我浏览视频,总是比较前一帧和当前帧。我从相对于前一帧添加的所有元素中提取边界框坐标,并存储最高的y坐标。从图像顶部看,最高y坐标属于图像下方最远的元素。因此,理论上,这应该给我一个指示,如果我正在填写幻灯片 实际上,我无法真正利用这些数据: 有关视频可在此处下载: 这是我

我有一个幻灯片视频,演示者在幻灯片上手写笔记:

我想创建一个程序,检测幻灯片是否由手写笔记填写,或者是否是新幻灯片

我想到的一种方法是文本的OCR,但这并不合适,因为这里唯一改变的文本不是手写的就是数学的

到目前为止我所做的: 我浏览视频,总是比较前一帧和当前帧。我从相对于前一帧添加的所有元素中提取边界框坐标,并存储最高的y坐标。从图像顶部看,最高y坐标属于图像下方最远的元素。因此,理论上,这应该给我一个指示,如果我正在填写幻灯片

实际上,我无法真正利用这些数据:

有关视频可在此处下载:

这是我的密码:


有人有什么想法吗?

作为问题的第一步,我可能只想计算两幅图像之间不同的像素数。它有几个理想的特性:

这是一个实际的距离度量。 从计算上来说,这是非常便宜的。 手写内容较多的幻灯片与原始幻灯片的距离较低,例如,如果您逐渐增加了书写内容,并希望订购这些内容,则手写内容较多的幻灯片与原始幻灯片的距离较远。 如果幻灯片上有适度的内容,你不一定会有任何两张不相关的幻灯片,而不是两张相同但笔迹不同的幻灯片,尤其是像这样的薄型书写。 当然,这不是一个完美的解决方案-例如,如果您通过拍照获得幻灯片,那么几乎每个幻灯片在每个像素上都会有所不同。花点时间考虑一下您的用例和数据收集方法

python中的图像通常表示为numpy数组。假设您也是这样,下面的示例将计算有问题的度量,或者可以很容易地修改以提供相似性而不是距离:

def dist(a, b):
    # Supposes some sort of pixel representation like bgr or hsl with
    # shape (w, h, other) or (h, w, other)
    return np.sum(np.sum(a!=b, axis=-1)!=0)

您可以尝试此代码,请参阅注释:

import cv2
import numpy as np

def get_bg_and_ink_level(frame):

    frame =  cv2.cvtColor(frame,cv2.COLOR_BGR2HSV)
    background=cv2.threshold(frame[:,:,2], 245, 255, cv2.THRESH_BINARY)[1]
    background_level=cv2.mean(background) # for future use if you need to select frames without hands. 
    ink_color_low = (117,60,150) 
    ink_color_high = (130,207,225) 
    only_ink = cv2.inRange(frame, ink_color_low, ink_color_high)
    ink_level=cv2.mean(only_ink)
    return background_level[0], ink_level[0]

vidcap = cv2.VideoCapture('0_0.mp4')
success,frame = vidcap.read()
bg = []
ink=[]
i=0
while success:
   lv= get_bg_and_ink_level(frame)
   bg.append(lv[0])
   ink.append(lv[1])
   success,frame = vidcap.read()
   
# search for frames where the blue ink is removed from the picture. 
d_ink=np.diff(ink)
d_ink[-1]=-2.0 #add last frame
idx=np.where(d_ink<-1.0)

#save frames
for i in idx[0]:
    vidcap.set(cv2.CAP_PROP_POS_FRAMES, i)
    flag, frame = vidcap.read()
    out_name='frame'+str(i)+'.jpg'
    cv2.imwrite(out_name, frame)
结果15708帧:

你的标题与你的问题明显不同。标题意味着您知道这两个图像是从同一个开始的,您只想知道添加了什么。你的问题意味着你需要确定两者是否有共同的基础。@MarkSetchell嗯,是的,你是对的。你对标题有更好的建议吗?1:对两幅图像进行形态学放大,然后比较它们。必须选择内核,以便它完全删除手写文本。2:如果所有手写文本都是用蓝色笔书写的,那么您可以选择所有蓝色,并在比较时忽略这些区域。为了进行比较,您可以使用诸如MAE、RMSE、MSE等指标。看@AlexAlex这些其实是一些非常好的想法。不幸的是,如果您删除手写内容,幻灯片本身在幻灯片之间的变化不大,因为它已被检测为新幻灯片。非常感谢您的回答!我已经更新了问题并添加了代码。你可能想看看。谢谢!非常感谢您的回答!我认为这已经是一个很好的方法了!唯一的问题是,在视频中实际上有3个幻灯片更改,并且使用您的代码,我只得到最后一个。我在输出3+1最后一帧时得到4个图像。用墨水画图。您测试此视频或更大的分辨率?可能值得在idx=np行中增加阈值-1.0。其中,我有6200、10869、15708、20580帧的jpeg图片。很抱歉,由于某种原因,我的电脑在第一次运行时出现了错误。我确实再次运行了你的代码,现在我得到了相同的结果!真令人印象深刻!非常感谢你的精彩回答!
import cv2
import numpy as np

def get_bg_and_ink_level(frame):

    frame =  cv2.cvtColor(frame,cv2.COLOR_BGR2HSV)
    background=cv2.threshold(frame[:,:,2], 245, 255, cv2.THRESH_BINARY)[1]
    background_level=cv2.mean(background) # for future use if you need to select frames without hands. 
    ink_color_low = (117,60,150) 
    ink_color_high = (130,207,225) 
    only_ink = cv2.inRange(frame, ink_color_low, ink_color_high)
    ink_level=cv2.mean(only_ink)
    return background_level[0], ink_level[0]

vidcap = cv2.VideoCapture('0_0.mp4')
success,frame = vidcap.read()
bg = []
ink=[]
i=0
while success:
   lv= get_bg_and_ink_level(frame)
   bg.append(lv[0])
   ink.append(lv[1])
   success,frame = vidcap.read()
   
# search for frames where the blue ink is removed from the picture. 
d_ink=np.diff(ink)
d_ink[-1]=-2.0 #add last frame
idx=np.where(d_ink<-1.0)

#save frames
for i in idx[0]:
    vidcap.set(cv2.CAP_PROP_POS_FRAMES, i)
    flag, frame = vidcap.read()
    out_name='frame'+str(i)+'.jpg'
    cv2.imwrite(out_name, frame)