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