-
异常行为识别
2016-03-16 17:07:38异常行为识别 -
实时 摔倒识别 /运动分析/打架等异常行为识别/控制手势识别等所有行为识别全家桶 原理 + 代码 + 数据+ 模型...
2021-03-02 15:20:20大家好,我是cv君,很多大创,比赛,项目,工程,科研,学术的炼丹术士问我上述这些识别,该怎么做,怎么选择框架,今天可以和大家分析一下一些方案: 用单帧目标检测做的话,前后语义相关性很差(也有文章目录
大家好,我是cv君,很多大创,比赛,项目,工程,科研,学术的炼丹术士问我上述这些识别,该怎么做,怎么选择框架,今天可以和大家分析一下一些方案:
用单帧目标检测做的话,前后语义相关性很差(也有优化版),效果不能达到实际项目需求,尤其是在误检上较难,并且目标检测是需要大量数据来拟合的。标注需求极大。
用姿态加目标检测结合的方式,效果是很不错的,不过一些这样类似Two stage的方案,速度较慢(也有很多实时的),同样有着一些不能通过解决时间上下文的问题。
即:摔倒检测 我们正常是应该有一个摔倒过程,才能被判断为摔倒的,而不是人倒下的就一定是摔倒(纯目标检测弊病)
运动检测 比如引体向上,和高抬腿计数,球类运动,若是使用目标检测做,那么会出现什么问题呢? 引体向上无法实现动作是否规范(当然可以通过后处理判断下巴是否过框,效果是不够人工智能的),高抬腿计数,目标检测是无法计数的,判断人物的球类运动,目标检测是有很大的误检的:第一种使用球检测,误检很大,第二种使用打球手势检测,遇到人物遮挡球类,就无法识别目标,在标注上也需要大量数据…
今天cv君铺垫了这么多,只是为了给大家推荐一个全新出炉视频序列检测方法,目前代码已开源至Github:https://github.com/CVUsers/CV-Action欢迎star~
欢迎移步。只需要很少的训练数据,就可以拟合哦!不信你来试试吧~几个训练集即可。
神经网络使用的是这两个月开源的实时动作序列强分类神经网络:realtimenet 。
我的github将收集 所有的上述说到的动作序列视频数据,训练出能实用的检测任务:目前实现了手势控制的检测,等等,大家欢迎关注公众号,后续会接着更新。
开始
目前以手势和运动识别为例子,因为cv君没什么数据哈哈
项目演示:
本人做的没转gif,所以大家可以看看其他的演示效果图,跟我的是几乎一样的~ 只是训练数据不同
一、 基本过程和思想
基本思想是将数据集中视频及分类标签转换为图像(视频帧)和其对应的分类标签,也可以不标注,单独给一个小视频标注上分类类别,再采用CNN网络对图像进行训练学习和测试,将视频分类问题转化为图形分类问题。具体步骤包括:
(1) 对每个视频(训练和测试视频)以一定的FPS截出视频帧(jpegs)保存为训练集和测试集,将对图像的分类性能作为所对应视频的分类性能
(2)训练一个人物等特征提取模型,并采用模型融合策略,一个特征提取,一个分类模型。特征工程部分通用人物行为,分类模型,训练自己的类别的分类模型即可。
(4) 训练完成后载入模型对test set内所有的视频帧进行检查验证,得出全测试集上的top1准确率和top5准确率输出。
(5)实时检测。
二 、视频理解还有哪些优秀框架
第一个 就是我github这个了,比较方便,但不敢排前几,因为没有什么集成,
然后MMaction ,就是视频理解框架了,众所周知,他们家的东西很棒
第二个就是facebook家的一些了,
再下来基本上就不多了,全面好用的实时框架。
好,所以我们先来说说我的使用过程。
三、效果体验~使用
体验官方的一些模型 (模型我已经放在里面了)
pip install -r requirements.txt
将模型放置此处:
resources ├── backbone │ ├── strided_inflated_efficientnet.ckpt │ └── strided_inflated_mobilenet.ckpt ├── fitness_activity_recognition │ └── ... ├── gesture_recognition │ └── ... └── ...
首先,请试用我们提供的演示。在sense/examples目录中,您将找到3个Python脚本, run_gesture_recognition.py ,健身_跟踪器 run_fitness_tracker.py .py,并运行卡路里_估算 run_calorie_estimation .py. 启动每个演示就像在终端中运行脚本一样简单,如下所述。
手势:
cd examples/
python run_gesture_recognition.py
健身_跟踪器:
python examples/run_fitness_tracker.py --weight=65 --age=30 --height=170 --gender=female
--camera_id=CAMERA_ID ID of the camera to stream from --path_in=FILENAME Video file to stream from. This assumes that the video was encoded at 16 fps.
卡路里计算
python examples/run_calorie_estimation.py --weight=65 --age=30 --height=170 --gender=female
三、训练自己数据集步骤
首先 clone一下我的github,或者原作者github,
然后自己录制几个视频,比如我这里capture 一个类别,录制了几个视频,可以以MP4 或者avi后缀,再来个类别,再录制一些视频,以名字为类别。
然后
cd tools\sense_studio\sense_studio.py
这一步,会显示:
然后,打开这个网址:
来到前端界面
点击一下start new project
这样编写
然后点击create project 即可制作数据。
但是官方的制作方法是有着严重bug的~我们该怎么做呢!
下面,我修改后,可以这样!
这里请仔细看:
我们在sense_studio 文件夹下,新建一个文件夹:我叫他cvdemo1
然后新建两个文件夹:videos_train 和videos_valid 里面存放的capture是你的类别名字的数据集,capture存放相关的训练集,click存放click的训练集,同样的videos_valid 存放验证集,
在cvdemo1文件夹下新建project_config.json ,里面写什么呢? 可以复制我的下面的代码:
{ "name": "cvdemo1", "date_created": "2021-02-03", "classes": { "capture": [ "capture", "capture" ], "click": [ "click", "click" ] } }
里面的name 改成你的文件夹名字即可。
就这么简单!
然后就可以训练:
python train_classifier.py 你可以将main中修改一下。将path in修改成我们的训练数据地址,即可,其他的修改不多,就按照我的走即可,
# Parse arguments # args = docopt(__doc__) path_in = './sense_studio/cvdemo1/' path_out = path_in os.makedirs(path_out, exist_ok=True) use_gpu = True path_annotations_train = None path_annotations_valid =None num_layers_to_finetune = 9 temporal_training = False # Load feature extractor feature_extractor = feature_extractors.StridedInflatedEfficientNet() checkpoint = torch.load('../resources/backbone/strided_inflated_efficientnet.ckpt') feature_extractor.load_state_dict(checkpoint) feature_extractor.eval() # Get the require temporal dimension of feature tensors in order to # finetune the provided number of layers. if num_layers_to_finetune > 0: num_timesteps = feature_extractor.num_required_frames_per_layer.get(-num_layers_to_finetune) if not num_timesteps: # Remove 1 because we added 0 to temporal_dependencies num_layers = len(feature_extractor.num_required_frames_per_layer) - 1 raise IndexError(f'Num of layers to finetune not compatible. ' f'Must be an integer between 0 and {num_layers}') else: num_timesteps = 1
训练特别快,10分钟即可,
然后,你可以运行run_custom_classifier.py
# Parse arguments # args = docopt(__doc__) camera_id = 0 path_in = None path_out = None custom_classifier = './sense_studio/cvdemo1/' title = None use_gpu = True # Load original feature extractor feature_extractor = feature_extractors.StridedInflatedEfficientNet() feature_extractor.load_weights_from_resources('../resources/backbone/strided_inflated_efficientnet.ckpt') # feature_extractor = feature_extractors.StridedInflatedMobileNetV2() # feature_extractor.load_weights_from_resources(r'../resources\backbone\strided_inflated_mobilenet.ckpt') checkpoint = feature_extractor.state_dict() # Load custom classifier checkpoint_classifier = torch.load(os.path.join(custom_classifier, 'classifier.checkpoint')) # Update original weights in case some intermediate layers have been finetuned name_finetuned_layers = set(checkpoint.keys()).intersection(checkpoint_classifier.keys()) for key in name_finetuned_layers: checkpoint[key] = checkpoint_classifier.pop(key) feature_extractor.load_state_dict(checkpoint) feature_extractor.eval() print('[debug] net:', feature_extractor) with open(os.path.join(custom_classifier, 'label2int.json')) as file: class2int = json.load(file) INT2LAB = {value: key for key, value in class2int.items()} gesture_classifier = LogisticRegression(num_in=feature_extractor.feature_dim, num_out=len(INT2LAB)) gesture_classifier.load_state_dict(checkpoint_classifier) gesture_classifier.eval() print(gesture_classifier)
同样修改路径即可。
结果就可以实时检测了
原代码解读
同样的,我们使用的是使用efficienct 来做的特征,你也可以改成mobilenet 来做,有示例代码,就是训练的时候,用mobilenet ,检测的时候也是,只需要修改几行代码即可。
efficienct 提取特征部分代码:
class StridedInflatedEfficientNet(StridedInflatedMobileNetV2): def __init__(self): super().__init__() self.cnn = nn.Sequential( ConvReLU(3, 32, 3, stride=2), InvertedResidual(32, 24, 3, spatial_stride=1), InvertedResidual(24, 32, 3, spatial_stride=2, expand_ratio=6), InvertedResidual(32, 32, 3, spatial_stride=1, expand_ratio=6, temporal_shift=True), InvertedResidual(32, 32, 3, spatial_stride=1, expand_ratio=6), InvertedResidual(32, 32, 3, spatial_stride=1, expand_ratio=6), InvertedResidual(32, 56, 5, spatial_stride=2, expand_ratio=6), InvertedResidual(56, 56, 5, spatial_stride=1, expand_ratio=6, temporal_shift=True, temporal_stride=True), InvertedResidual(56, 56, 5, spatial_stride=1, expand_ratio=6), InvertedResidual(56, 56, 5, spatial_stride=1, expand_ratio=6), InvertedResidual(56, 112, 3, spatial_stride=2, expand_ratio=6), InvertedResidual(112, 112, 3, spatial_stride=1, expand_ratio=6, temporal_shift=True), InvertedResidual(112, 112, 3, spatial_stride=1, expand_ratio=6), InvertedResidual(112, 112, 3, spatial_stride=1, expand_ratio=6), InvertedResidual(112, 112, 3, spatial_stride=1, expand_ratio=6, temporal_shift=True, temporal_stride=True), InvertedResidual(112, 112, 3, spatial_stride=1, expand_ratio=6), InvertedResidual(112, 160, 5, spatial_stride=1, expand_ratio=6), InvertedResidual(160, 160, 5, spatial_stride=1, expand_ratio=6, temporal_shift=True), InvertedResidual(160, 160, 5, spatial_stride=1, expand_ratio=6), InvertedResidual(160, 160, 5, spatial_stride=1, expand_ratio=6), InvertedResidual(160, 160, 5, spatial_stride=1, expand_ratio=6, temporal_shift=True), InvertedResidual(160, 160, 5, spatial_stride=1, expand_ratio=6), InvertedResidual(160, 272, 5, spatial_stride=2, expand_ratio=6), InvertedResidual(272, 272, 5, spatial_stride=1, expand_ratio=6, temporal_shift=True), InvertedResidual(272, 272, 5, spatial_stride=1, expand_ratio=6), InvertedResidual(272, 272, 5, spatial_stride=1, expand_ratio=6, temporal_shift=True), InvertedResidual(272, 272, 5, spatial_stride=1, expand_ratio=6), InvertedResidual(272, 272, 5, spatial_stride=1, expand_ratio=6), InvertedResidual(272, 272, 5, spatial_stride=1, expand_ratio=6), InvertedResidual(272, 272, 5, spatial_stride=1, expand_ratio=6), InvertedResidual(272, 448, 3, spatial_stride=1, expand_ratio=6), ConvReLU(448, 1280, 1) )
这个InvertedResidual 在这,
class InvertedResidual(nn.Module): # noqa: D101 def __init__(self, in_planes, out_planes, spatial_kernel_size=3, spatial_stride=1, expand_ratio=1, temporal_shift=False, temporal_stride=False, sparse_temporal_conv=False): super().__init__() assert spatial_stride in [1, 2] hidden_dim = round(in_planes * expand_ratio) self.use_residual = spatial_stride == 1 and in_planes == out_planes self.temporal_shift = temporal_shift self.temporal_stride = temporal_stride layers = [] if expand_ratio != 1: # Point-wise expansion stride = 1 if not temporal_stride else (2, 1, 1) if temporal_shift and sparse_temporal_conv: convlayer = SteppableSparseConv3dAs2d kernel_size = 1 elif temporal_shift: convlayer = SteppableConv3dAs2d kernel_size = (3, 1, 1) else: convlayer = nn.Conv2d kernel_size = 1 layers.append(ConvReLU(in_planes, hidden_dim, kernel_size=kernel_size, stride=stride, padding=0, convlayer=convlayer)) layers.extend([ # Depth-wise convolution ConvReLU(hidden_dim, hidden_dim, kernel_size=spatial_kernel_size, stride=spatial_stride, groups=hidden_dim), # Point-wise mapping nn.Conv2d(hidden_dim, out_planes, 1, 1, 0), # nn.BatchNorm2d(out_planes) ]) self.conv = nn.Sequential(*layers) def forward(self, input_): # noqa: D102 output_ = self.conv(input_) residual = self.realign(input_, output_) if self.use_residual: output_ += residual return output_ def realign(self, input_, output_): # noqa: D102 n_out = output_.shape[0] if self.temporal_stride: indices = [-1 - 2 * idx for idx in range(n_out)] return input_[indices[::-1]] else: return input_[-n_out:]
我们finetune自己的数据集
def extract_features(path_in, net, num_layers_finetune, use_gpu, num_timesteps=1): # Create inference engine inference_engine = engine.InferenceEngine(net, use_gpu=use_gpu) # extract features for dataset in ["train", "valid"]: videos_dir = os.path.join(path_in, f"videos_{dataset}") features_dir = os.path.join(path_in, f"features_{dataset}_num_layers_to_finetune={num_layers_finetune}") video_files = glob.glob(os.path.join(videos_dir, "*", "*.avi")) print(f"\nFound {len(video_files)} videos to process in the {dataset}set") for video_index, video_path in enumerate(video_files): print(f"\rExtract features from video {video_index + 1} / {len(video_files)}", end="") path_out = video_path.replace(videos_dir, features_dir).replace(".mp4", ".npy") if os.path.isfile(path_out): print("\n\tSkipped - feature was already precomputed.") else: # Read all frames compute_features(video_path, path_out, inference_engine, num_timesteps=num_timesteps, path_frames=None, batch_size=16) print('\n')
构建数据的dataloader
def generate_data_loader(dataset_dir, features_dir, tags_dir, label_names, label2int, label2int_temporal_annotation, num_timesteps=5, batch_size=16, shuffle=True, stride=4, path_annotations=None, temporal_annotation_only=False, full_network_minimum_frames=MODEL_TEMPORAL_DEPENDENCY): # Find pre-computed features and derive corresponding labels tags_dir = os.path.join(dataset_dir, tags_dir) features_dir = os.path.join(dataset_dir, features_dir) labels_string = [] temporal_annotation = [] if not path_annotations: # Use all pre-computed features features = [] labels = [] for label in label_names: feature_temp = glob.glob(f'{features_dir}/{label}/*.npy') features += feature_temp labels += [label2int[label]] * len(feature_temp) labels_string += [label] * len(feature_temp) else: with open(path_annotations, 'r') as f: annotations = json.load(f) features = ['{}/{}/{}.npy'.format(features_dir, entry['label'], os.path.splitext(os.path.basename(entry['file']))[0]) for entry in annotations] labels = [label2int[entry['label']] for entry in annotations] labels_string = [entry['label'] for entry in annotations] # check if annotation exist for each video for label, feature in zip(labels_string, features): classe_mapping = {0: "counting_background", 1: f'{label}_position_1', 2: f'{label}_position_2'} temporal_annotation_file = feature.replace(features_dir, tags_dir).replace(".npy", ".json") if os.path.isfile(temporal_annotation_file): annotation = json.load(open(temporal_annotation_file))["time_annotation"] annotation = np.array([label2int_temporal_annotation[classe_mapping[y]] for y in annotation]) temporal_annotation.append(annotation) else: temporal_annotation.append(None) if temporal_annotation_only: features = [x for x, y in zip(features, temporal_annotation) if y is not None] labels = [x for x, y in zip(labels, temporal_annotation) if y is not None] temporal_annotation = [x for x in temporal_annotation if x is not None] # Build dataloader dataset = FeaturesDataset(features, labels, temporal_annotation, num_timesteps=num_timesteps, stride=stride, full_network_minimum_frames=full_network_minimum_frames) data_loader = torch.utils.data.DataLoader(dataset, shuffle=shuffle, batch_size=batch_size) return data_loader
如何实时检测视频序列的?
这个问题,主要是通过 系列时间内帧间图像组合成一个序列,送到网络中进行分类的,可以在许多地方找到相关参数,比如 display.py :
class DisplayClassnameOverlay(BaseDisplay): """ Display recognized class name as a large video overlay. Once the probability for a class passes the threshold, the name is shown and stays visible for a certain duration. """ def __init__( self, thresholds: Dict[str, float], duration: float = 2., font_scale: float = 3., thickness: int = 2, border_size: int = 50, **kwargs ): """ :param thresholds: Dictionary of thresholds for all classes. :param duration: Duration in seconds how long the class name should be displayed after it has been recognized. :param font_scale: Font scale factor for modifying the font size. :param thickness: Thickness of the lines used to draw the text. :param border_size: Height of the border on top of the video display. Used for correctly centering the displayed class name on the video. """ super().__init__(**kwargs) self.thresholds = thresholds self.duration = duration self.font_scale = font_scale self.thickness = thickness self.border_size = border_size self._current_class_name = None self._start_time = None def _get_center_coordinates(self, img: np.ndarray, text: str): textsize = cv2.getTextSize(text, FONT, self.font_scale, self.thickness)[0] height, width, _ = img.shape height -= self.border_size x = int((width - textsize[0]) / 2) y = int((height + textsize[1]) / 2) + self.border_size return x, y def _display_class_name(self, img: np.ndarray, class_name: str): pos = self._get_center_coordinates(img, class_name) put_text(img, class_name, position=pos, font_scale=self.font_scale, thickness=self.thickness) def display(self, img: np.ndarray, display_data: dict): now = time.perf_counter() if self._current_class_name and now - self._start_time < self.duration: # Keep displaying the same class name self._display_class_name(img, self._current_class_name) else: self._current_class_name = None for class_name, proba in display_data['sorted_predictions']: if class_name in self.thresholds and proba > self.thresholds[class_name]: # Display new class name self._display_class_name(img, class_name) self._current_class_name = class_name self._start_time = now break return img
对了
每个类别只需要5个左右的视频,即可得到不错的效果嗷~
欢迎Star github~因为后续会更新标题的所有模型。
欢迎各位目标检测以及其他AI领域的朋友进入精品AI知识星球
本星球面向所有AI领域的同学,工程师,甲方,乙方,爱好者等~
Q:什么是知识星球?他和微信QQ技术交流群的区别是什么?
A: 由于交流群水群太多,故而建立知识星球,星球里面有问有答,多对多的知识分享与问答。
Q:为什么要进知识星球?
A:这个知识星球里面专业人士较多,术业有专攻,都是AI领域的先行者,能得到他们的帮助,甚至与其交朋友,事半功倍,最重要的是,作为AI领域学子,进入以后能督促学习,养成自律的好习惯~
Q:为什么要付费?
A:由于内容质量高,不希望白嫖。
Q:里面有哪些人?
A: 清华北大北理中科大学子,Intel ,达摩院,腾讯,字节等大厂大佬,90% AI方向研究生学历以上,一群友善好学,有问必答的后浪们~
一个专注AI领域的知识星球 正式成立啦~星球联系我,获取数据和模型嗷~
-
基于神经网络的交互式异常行为识别研究
2021-01-26 13:27:02在智能安防领域中,异常行为识别一直是该领域的一个研究热点。但目前的研究技术仅能够识别简单的行为特征,对于复杂行为的识别还存在诸多问题。随着人工智能技术的不断发展以及在行为识别上的应用,可以尝试通过深度... -
公交异常行为识别解决方案_0130
2019-02-16 13:09:10公交异常行为识别解决方案_0130_深圳太古计算机系统有限公司 -
AI+智能公交异常行为识别解决方案.pptx
2021-04-11 13:15:01AI+智能公交异常行为识别解决方案 -
论文研究-基于运动特征的人体异常行为识别 .pdf
2019-08-15 15:38:39基于运动特征的人体异常行为识别,桑海峰,郭昊,为了提高监控视频中人体异常行为识别的实时性和准确率,提出了基于运动特征的人体异常行为识别方法。利用分块更新的背景差法从图 -
基于深度学习与稀疏光流的人群异常行为识别.pdf
2020-05-17 18:01:39基于深度学习与稀疏光流的人群异常行为识别.pdf -
基于深度学习网络模型的鱼群异常行为识别方法
2018-06-07 20:25:49基于深度学习网络模型的鱼群异常行为识别方法 -
论文研究-基于KOD能量特征的群体异常行为识别.pdf
2019-07-22 23:44:04在群体异常行为识别过程中, 针对传统特征易受目标遮挡影响导致其对群体行为的弱描述性问题, 提出一种基于KOD(kinetic orientation distance)能量特征的群体异常行为识别方法。该能量特征忽略群体中相互遮挡的个体... -
论文研究-基于用户意图的Android程序异常行为识别 .pdf
2019-08-22 03:41:09基于用户意图的Android程序异常行为识别,傅建明,丁爽,移动互联网时代背景下,Android作为主流的手机操作系统,其安全问题日益严峻。但无论恶意代码如何伪装,最终都会落实到非用户授权�� -
MATLAB视频人体异常行为识别
2020-02-28 23:08:49本系统为人体异常行为检测系统 本文件夹下共包含12个文件 其中matlab代码文件9个,视频源文件夹1个(内含4个视频),指导视频一个,说明文档一个 其中仅需要打开Main_Test.fig文件,点击运行即可使用 -
MATLAB视频人体异常行为识别.zip
2021-01-29 16:35:54Matlab人体异常行为检测,可检测商城小偷,异常可疑人员 -
基于质心运动轨迹法在ATM视频监控中的异常行为识别
2013-05-31 17:41:29基于质心运动轨迹法在ATM视频监控中的异常行为识别 -
人类异常行为识别数据集汇总【转载】(附链接)
2019-03-27 10:48:30数据是人群行为识别研究的基础,为了更加方便开展相关研究工作,陆续有研究机构采集人群异常行 为数据,构建了相关数据库并进行公开,从而一定程度推动了人群行为研究.这些数据库为行为识别的研 究提供了重要参考依据....参考论文:人群异常识别技术研究进展_魏永超
数据是人群行为识别研究的基础, 为了更加方便开展相关研究工作, 陆续有研究机构采集人群异常行
为数据, 构建了相关数据库并进行公开, 从而一定程度推动了人群行为研究. 这些数据库为行为识别的研
究提供了重要参考依据. 下面将对代表性的人群行为数据库的进行概括。(1)USCD(University of California, San Diego)异常检测数据库[32]. 数据由加州大学圣地亚哥分校创建,
数据是通过安装在一定高度、俯视人行道的摄像机,采集自然状态下发生的异常行为. 异常行为包含两类:
非人实体闯入和人行为异常. 异常种类包括骑自行车、滑冰、小推车、行人横穿人行道、侵入草地等, 同
时也记录人在轮椅上的几个实例. 数据由98 个视频组成, 被分成2 不同的场景的子集, 每个场景录制的视
频录像被分成约200 帧的各个片段. 该数据库主要针对是人群中个体行为的识别研究.
(2) UMN(University of Minnesota)数据库[33]. 明尼苏达州大学创建的一个数据库, 由11 个视频组成, 包
含了正常和异常视频. 每个视频起始部分是正常行为,随后为异常行为视频序列. 人群异常行为主要包括:人群单方向跑动、人群四散等. 该视频数据库采集的视频人为安排的异常行为. 该数据库针对的整体人群行为识别.
(3) UCF(University of Central Florida)数据库[34].该数据库由中佛罗里达大学创建, 包含了99 个视频片段. 该 数 据 库 主 要 是 收 集BBC Motion Gallery 、Youtube、Thought Equity 和Getty-Images 等网站视频数据, 用于公开的科学研究. 特点是在照明和视野的变化, 可以用于拥挤场面开发的算法的性能评价. 该数据集包含的人群和其他高密度移动物体的视频. 可以用于人群行为识别研究以及拥挤人群行为研究.
(4) VIF(violent flow)数据库[35]. 由以色列开放大学创建的人群数据库, 主要关注的是人群暴力行为.由246个视频组成, 所有的视频从YouTube 下载的, 视频来源是真实的现实暴力录影. 数据库旨在为检验暴力/非暴力分类和暴力标准提供测试依据. 视频中, 最短剪辑的持续时间为1.04 秒,最长剪辑6.52 秒, 视频片段的平均长度为3.60 秒.下载链接:https://www.openu.ac.il/home/hassner/data/violentflows/
(5) CUHK(Chinese University of Hong Kong) 数据库[36]. 该数据集用于拥挤场景下活动或行为研究. 它包括两个子数据集: 交通数据集(麻省理工学院的交通录像)和行人数据集. 交通数据集包括90 分钟长的交通视频序列, 一些抽样帧的行人基础事实是手动标记的. 行人数据集记录了纽约的大中央车站, 包含一个长30 分钟的视频, 无任何标记或事实的数据.
(6) MALL 数据库[37]. 该数据集有两个子集: 第一是三个不同的密集的十字路口近60 分钟的交通流视频; 第二个是从一个可公开访问的购物中心的网络相机上获取的视频. 对2000 帧视频中的60000行人进行了标记, 每一个行人的头部位置也进行了标记. 因此,这个数据集方便于人群计数和轮廓分析的研究.下载地址:https://amandajshao.github.io/projects/WWWCrowdDataset.html(WWW dataset)
相关链接:http://personal.ie.cuhk.edu.hk/~ccloy/datasets.html
(7) PETS 2009(Performance Evaluation of Trackingand Surveillance) 数据库[38]. 此数据集包含了多传感器的不同人群的活动序列, 共有9 个视频. 它由五个组成部分: 校准数据、训练数据、计数和密度估计数据、跟踪数据以及流量分析和事件识别数据. 每个子集包含多个视频序列, 每个序列由4 到8 个不同视角拍摄.下载链接:http://www.cvg.reading.ac.uk/PETS2009/data.html
(8) RWC(Rodriguezs Web-Collected)收集网络数据库[39]. 罗德里格斯的网络收集的数据集, 由520 个视频组成. 抓取和下载搜索引擎和素材网站的视频源,例如, Gettyimages 和YouTube 等, 构建其数据库. 除了大量人群视频外, 数据集还随机从集合中选择所有运动的人中, 记录了100 个人的地面真实轨迹. 该数据集是不向公众开放的.下载链接:https://www.di.ens.fr/willow/research/datadriven/
下载链接:http://www.mikelrodriguez.com/datasets-and-source-code/#datadriven
(9) UH(University of Haifa)数据库[40]. 视频来自五个采集点的八个摄像机, 分别是食堂1 个, 地铁入口1个, 地铁出口1 个, 车库出口1 个, 公交车站1 个, 商场3 个, 食堂和公交车站采用人为架设摄像机采集,其它地点来自监控. 所有视频中事件都进行了人为标记, 方便算法的测试. 数据库从食堂采集11 分钟视频,地铁入口1 小时36 分视频, 地铁出口43 分钟视频, 车库出口5 小时20 分视频, 公交车站2 分20 秒视频, 商场共155 分钟视频. 异常行为有自然发生, 也有人为设计的.下载地址:datasets are available for public use upon request
(10) UCF-Crime
下载链接:https://webpages.uncc.edu/cchen62/dataset.html
(11) BEHAVE
下载链接:http://groups.inf.ed.ac.uk/vision/BEHAVEDATA/INTERACTIONS/
人群异常数据库已经有一定的规模, 且基本都是公开的, 可以用于人群异常行为的研究. 但是, 目前的人群数据库还没有形成体系, 更多的都是研究团队自己采集的视频, 没有相关标准, 视频种类繁多, 这样一定程度限制了人群行为识别的研究. 因此, 标准的人群数据库的建立是需要进一步开展的相关工作.参考文献:
[32] UCSD Anomaly Detection Dataset, http://www.svcl.ucsd.edu/projects/anomaly/dataset.htm.
[33] UMN Crowd Dataset, http://mha.cs.umn.edu/projevents.shtml#crowd.
[34] Ali S, Shah M. A lagrangian particle dynamics approach forcrowd flow segmentation and stability analysis. IEEEConference on Computer Vision and Pattern Recognition.Minneapolis. CurranAssociates, Inc. 2007. 1–6.
[35] Violence-flows Dataset, http:. www.openu.ac.il/ home/hassner/data/violentflows/index.html.
[36] Wang X, Ma X, Grimson WEL. Unsupervised activityperception in crowded and complicated scenes usinghierarchical bayesian models. IEEE Trans. on PatternAnalysis and Machine Intelligence, 2009, 31(3): 539–555.
[37] Loy CC, Chen K, Gong S, Xiang T. Crowd counting andprofiling: Methodology and evaluation. Modeling,Simulation and Visual Analysis of Crowds, Springer. 2013,
11: 347–382.[38] PETS2009 Dataset, http://www.cvg.rdg.ac.uk/PETS2009.
[39] Rodriguez M, Sivic J, Laptev I, Audibert JY. Data-drivencrowd analysis in videos. IEEE International Conference onComputer Vision. Barcelona. Curran Associates, Inc. 2011.1235–1242.
[40] Adam A, Rivlin E, Shimshoni I, Reinitz D. Robust real-timeunusual event detection using multiple fixed-locationmonitors. IEEE Trans. on Pattern Analysis and MachineIntelligence, 2008, 30(3): 555–560. -
论文研究-近似周期运动的人体异常行为识别.pdf
2019-09-13 04:47:33图像的绘画效果由平滑纹理,保持并加强边角获得。给出一种鲁棒的由真实图像自动生成相应绘画效果的算法。算法根据图像的局部结构,自适应地调节滤波器的带宽与形状,来模拟画笔宽度和绘画技法。... -
复杂场景下基于人工智能的变电站内异常行为识别与检测方法.pdf
2020-09-14 17:28:28(19)中华人民共和国国家知识产权局 (12)发明专利申请 (10)申请公布号 CN 111339883 A (43)申请公布日 2020.06.26 (21)申请号 202010102771.7 G06K 9/32(2006.01) G06N 3/04(2006.01) (22)申请日 2020.02.19 G06N 3/... -
运动人体检测与异常行为识别
2013-06-03 23:48:33有哪位大神了解这方面的研究?能不能给我推荐几个国外的网站和相关研究人员的个人主页地址。多谢! -
计算机视觉与深度学习 | 卷积神经网络实现异常行为识别(目标分割与提取)
2021-01-26 20:03:29################################################ ...利用所获取前景目标信息,自动判断监控视频中有无人群短时聚集、人群惊慌逃散、群体规律性变化(如跳舞、列队排练等)、物体爆炸、建筑物倒塌等异常事件################################################
博主github:https://github.com/MichaelBeechan
博主CSDN:https://blog.csdn.net/u011344545
################################################问题
- 利用所获取前景目标信息,自动判断监控视频中有无人群短时聚集、人群惊慌逃散、群体规律性变化(如跳舞、列队排练等)、物体爆炸、建筑物倒塌等异常事件。
- 场景的分类就是按照人类的思维方式来模拟场景的视觉感知,用来区分各类目标场景。
- 针对这个问题,本文将就人群的异常行为识别进行主要的分析。人群行为检测设计的主要相关问题包括:人群运动区域检测、人群行为特征的提取、人群行为分类识别等内容。1)在人群运动区域检测方面,可以利用解决前几个问题的几种方法实现,包括背景减除法、帧差法、高斯混合模型法和光流法等。对人群运动区域进行准确检测。保证了后续研究工作的可靠性。2)研究并设计了一种特征提取及描述策略,将运动区域像素点计算得到的速度及方向信息应用于时空立方体中,使其适用于运动随意性较强的场景中的行为特征提取。将时空立方体特征与具有竞争机制的神经网络模型结合,提出了完整的人群异常行为识别方法。
思路
- 采用深度神经网络的方法对场景进行识别分类。本题围绕神经网络训练与识别,深度学习和卷积神经网络的新型标签机制的选择作为切入点,进行了深入的研究。
a)对人群场景进行子群体分割。在这里,利用的是一种基于时空信息约束的分割方法。首先利用背景建模和特征点跟踪的方法,获取视频图像帧中运动目标的时空信息;然后,利用前景中群体分布的空间区域信息,将空间上相邻近的人群划分为若干子群体;最后,群体通过一段时间内的运动相关性进行进一步的分割。这两种约束信息相互作用,得到具有运动一致性的子群体。
b)对人群进行行为检测,实现异常事件的检测和定位。提出一种基于深度卷积神经网络的异常行为检测方法。首先,以分割后的子群体为研究对象,我们定义了三种群体行为描述因子,这些描述因子综合体现了群体内部的相互作用、稳定性以及运动一致性等运动特征,以这些数据作为训练数据,可以更好地提取出不同场景中的行为特征。然后,我们将这些描述因子以及视频帧的像素特征一起,作为深度学习网络的输入进行训练,构建了包含多个卷积层和采样层的深度卷积神经网络。
人工神经网络
- 人工神经网络(Artificial Neural Networks,ANNs)是通过计算机模拟人类的中枢神经系统构建计算模型,从而让计算机像人脑一样进行学习和识别信息。与传统方法相比,神经网络具有并行、纠错、自我学习等优点,为解决一些复杂度较高的问题提供了一种简单有效的方法。
- 在神经网络中,每个神经元就是一个运算单元,神经元是构建神经网络最简单最基本的信息单位。我们将从最简单的单个神经元开始来讲述神经网络模型架构,单个神经元结构如图所示。
- 时间递归神经网络(recurrent neural network,简称 RNN)是一个随时间运作的神经网络,在每个时刻它接受一个输入向量,然后通过非线性激活函数更新它的隐含层状态,最后使用隐含层状态去预测当前时刻的输出 W。当前时刻隐含层的状态是由上一个时刻隐含层的状态及当前时刻的输入共同作用的结果。RNN 形成了一个丰富的模型类,因为它的隐含层状态能够存储信息的高维分布表示,而非线性动态则能够实现丰富和强大的计算,这些都允许 RNN 对具有高度复杂结构的序列进行建模,完成预测任务。RNN 在模型上具有很多种变化,例如 Elman 网 络,Jordan 网络,时间延迟神经网络和响应状态网络等。
- 深度学习是一个模拟人类大脑学习机制的过程,它采用多层神经网络对现实对象或者语音、文本等数据进行抽样表达,将抽取的特征与分类器结合到一个学习框架下,对相关对象进行分类识别等。
- 对于人的视觉系统,它采用分级的方式处理信息,如图 9-4 所示。在底层 V1区提取最底层的边缘特征信息,然后再由 V2 区提取 V1 区的形状或者目标局部的特征。将 V2 区特征再提取到更高层的局部目标,最终达到能够识别整个目标或者行为的最高抽象区。也就是说底层特征逐层组合得到高层特征,从低层到高层的特征表达能力越来越抽象,越来越能表达语义和意图。因此,深度学习就是借鉴这种层级体系,通过由下向上、由低级到高级逐层抽象的特征学习,以此构建深度网络模型模拟大脑解决模式识别难题。
基于 KLT 算法的运动轨迹提取
- 为了获得视频图像中群体在连续时间内的运动信息,我们需要逐帧跟踪目标人群。光流法是一种经典的跟踪方法,它研究的是像素的瞬时运动,目标人群在图像上是由像素点组成的,因此像素点的瞬时速度可以体现丰富的人群运动信息。光流研究的是三维世界中物体的实际运动在二维图像上的对应关系。由于运动目标和静态的背景的运动矢量之间存在差异,从而能够检测出运动前景。其中,KLT 是应用广泛的稀疏光流跟踪方法,因此在本文中选择该算法进行人群运动信息的提取。
- KLT( Kanade-Lucas-Tomasi)算法通过计算特定跟踪窗口 W 在图像序列帧间的灰度差平方和( Sum of Squared Differences,SSD,用𝜀表示),来进行特征点匹配,从而实现特征点跟踪的方法该算法的核心思想是将图像拆分成图像的分辨率由小到大的多层次的金字塔结构,从顶端分辨率较的图像开始,依次向下进行特征点匹配。
- 如图所示,左图为视频帧原图,右图中的蓝色圆点即为跟踪到的特征点。根据上文中的方法,我们将连续帧中跟踪到的特征点位置连起来,便得到跟踪点的轨迹特征。实验结果如下图所示。
- 如图所示,左图是监控视频原图,右图是将连续帧中跟踪点的运动轨迹连起来后得到的轨迹图。图中的不同彩色线条代表跟不同踪点的运动轨迹。
基于混合高斯背景建模的前景提取
- 为了获得目标群体的空间信息,需要获得目标群体的区域位置信息,即前景提取。前景提取是图像处理领域中的重要研究内容,它的目的是为了从视频序列中提取出我们感兴趣的前景目标,从而便于后续的行为分析。其基本思想在于将输入图像和背景模型相比较,根据差值等信息来判断不符合背景模型的异常情况,从而区别出前景像素和背景像素。
- 在本问题中,采用基于混合高斯背景建模的前景提取。关于混合高斯模型的介绍在解决问题 2 的内容里已经介绍的非常详细,在这里就不再赘述。该算法的结果如图所示。左图是场景原图,右图是经过高斯混合背景模型的前景提取后的图像。通过实验验证,混合高斯背景建模算法可以基本准确地将运动前景提取出来,不足之处在于有时会有“鬼影”出现,且有些背景细节会被划分为前景。
基于空间信息约束的群体划分
- 小群体的成员间具有运动一致性,而这种一致性可以通过个体成员和周围邻近成员的交互关系来表示。我们将运动一致性定义为两种:空间上的一致性和时间上的一致性。空间一致性反应了个体之间距离的远近,通常距离较近的个体会自发组成运动团体。而时间上的一致性则反应了个体运动的目的,同一个团体内的个体在一定时间内运动趋势相同。基于这两种运动一致性,本文提出了一种基于时空信息约束的密集群体分割方法。
基于时间信息约束的群体划分
现有算法的原理分析及仿真(CT 算法)
基于卷积神经网络的异常行为检测
- 一个卷积神经网络通常包含多个卷积层、池化层和归一化层,然后由全连接层将二维的 feature maps 连接成一个向量输入到最后的分类器,得到最终的概率输出。为了让学习网络更好地区分出各种场景和群体行为,我们不仅将图像本身作为输入,而且利用合适的群体运动描述因子,使得学习的结果更加准确。
异常行为定义
- 在实际监控场景中,对于异常行为的定义很难有一个统一的标准,因为异常行为往往在不同的情境下有不同的含义。常见的异常行为的定义有三种,第一种是按照事件发生的频率来判断是否异常,比如在一个公园中,大部分人都是以慢速在散步,突然有人奔跑穿过的频率的是很低的,此时就判断为异常行为。但是这种情况经常会发生误判的可能性,因为很多正常行为的发生频率也很低,比如一个空旷的道路,有人走过和有人骑车穿过发生的频率都很低,很难界定之间的差别。而且各种场景中各种事件发生的频率不一而足,要想每一种都进行分析判定,是很难做到的。
- 第二种定义是基于事件特征的,比如打架斗殴,非法聚集等,这些事件中,人群的密度显然是和正常行人的不同。但是这种定义方法忽略了事件发生的频率,在一些场景中,正常行为和异常行为的外观特征是近乎相似的,因此也容易产生误检。
- 第三种定义将异常事件归类为一些具有特定含义的事件,也就是将事件语义化,例如将一个事件发生的时间地点人物加标签。这种方法可以检测出前两个定义无法检测出的异常,从更加全面的角度描述异常事件。本文中,我们将基于这种思想对事件进行标注,并且利用前文得到的群体运动特性对异常事件进行学习。我们利用可以借鉴文献中的标注方法,将不同的场景按照不同的地点、人物主体、主体行为进行分类。
- 这种标注对场景、群体、人群行为的描述不够完善,但是很容易在后续的工作中进行扩展,加入新的标注关键词,使得学习网络更加智能。在经过深度学习网络得到不同标注的概率值后,可以很容易地判断是否有异常行为出现。
- 如上图所示,左边图为监控视频图像,右边的表格中是概率从高至低排列的由学习得到的标注。第一个场中 buy_ticket 的标注不够准确,但概率值已位列第四,前三个描述仍然十分准确;第二个场景中的前三个描述也是十分准确的,第四个 parade 存在一定的误差;第三个场景场景的判断也基本准确,第四个判断speech 存在误差。在实验过程中该方法的判断正确率达到 84%。