|
@@ -0,0 +1,189 @@
|
|
|
+/*
|
|
|
+ * @Description:
|
|
|
+ * @Version: 1.0
|
|
|
+ * @Autor: lishengyin
|
|
|
+ * @Date: 2022-03-22 14:00:46
|
|
|
+ * @LastEditors: lishengyin
|
|
|
+ * @LastEditTime: 2022-03-25 09:56:36
|
|
|
+ */
|
|
|
+#include "InfineFilter.h"
|
|
|
+
|
|
|
+namespace cnstream{
|
|
|
+
|
|
|
+ bool InfineFilter::Open(cnstream::ModuleParamSet paramSet){
|
|
|
+ if (paramSet.find("FilterId") != paramSet.end()) {
|
|
|
+ std::string json = paramSet["FilterId"];
|
|
|
+ rapidjson::Document doc;
|
|
|
+ if (doc.Parse<rapidjson::kParseCommentsFlag>(json.c_str()).HasParseError()) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ const auto end = doc.MemberEnd();
|
|
|
+ if(end == doc.FindMember("label")|| !(doc["label"].IsArray())){
|
|
|
+ return false;
|
|
|
+ }else{
|
|
|
+ const rapidjson::Value& objs = doc["label"];
|
|
|
+ for(size_t i = 0; i < objs.Size(); i++){
|
|
|
+ labels.push_back(objs[i].GetString());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ for(auto iter = labels.begin(); iter != labels.end(); iter++){
|
|
|
+ LOGE(InfineFilter) << *iter << ",";
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(paramSet.find("files") != paramSet.end()){
|
|
|
+ this->files = paramSet["files"];
|
|
|
+ }
|
|
|
+ if(paramSet.find("saveFilterResult") != paramSet.end()){
|
|
|
+ this->saveFilterResult = paramSet["saveFilterResult"] == "true" ? true : false;
|
|
|
+ }
|
|
|
+ if(paramSet.find("lock_period") != paramSet.end()){
|
|
|
+ std::string json = paramSet["lock_period"];
|
|
|
+ rapidjson::Document doc;
|
|
|
+ if (doc.Parse<rapidjson::kParseCommentsFlag>(json.c_str()).HasParseError()) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ const auto end = doc.MemberEnd();
|
|
|
+ if(end == doc.FindMember("start")|| !(doc["start"].IsInt())){
|
|
|
+ return false;
|
|
|
+ }else{
|
|
|
+ this->start = doc["start"].GetInt();
|
|
|
+ }
|
|
|
+ if(end == doc.FindMember("end")|| !(doc["end"].IsInt())){
|
|
|
+ return false;
|
|
|
+ }else{
|
|
|
+ this->end = doc["end"].GetInt();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ int InfineFilter::Process(std::shared_ptr<cnstream::CNFrameInfo> data){
|
|
|
+ CNDataFramePtr frame = data->collection.Get<CNDataFramePtr>(kCNDataFrameTag);
|
|
|
+ if (frame->width < 0 || frame->height < 0) {
|
|
|
+ LOGE(InfineFilter) << "InfineFilter module processed illegal frame: width or height may < 0.";
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ CNInferObjsPtr objs_holder = nullptr;
|
|
|
+ if (data->collection.HasValue(kCNInferObjsTag)) {
|
|
|
+ objs_holder = data->collection.Get<CNInferObjsPtr>(kCNInferObjsTag);
|
|
|
+ }
|
|
|
+
|
|
|
+ if(objs_holder->objs_.size() == 0){
|
|
|
+ this->TransmitData(data);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 过滤某些Id
|
|
|
+ for(auto iter = objs_holder->objs_.begin(); iter != objs_holder->objs_.end(); ){
|
|
|
+ std::shared_ptr<cnstream::CNInferObject> object = *iter;
|
|
|
+ if (!object) continue;
|
|
|
+ auto it = find(this->labels.begin(), this->labels.end(), object->id);
|
|
|
+ if(it != this->labels.end()){
|
|
|
+ iter = objs_holder->objs_.erase(iter);
|
|
|
+ }else{
|
|
|
+ iter++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 过滤星星、月亮、飞机
|
|
|
+ for(auto iter = objs_holder->objs_.begin(); iter != objs_holder->objs_.end();){
|
|
|
+ std::shared_ptr<cnstream::CNInferObject> object = *iter;
|
|
|
+ if (!object) continue;
|
|
|
+ if(!this->filter(frame->ImageBGR(), object)){
|
|
|
+ iter = objs_holder->objs_.erase(iter);
|
|
|
+ }else{
|
|
|
+ iter++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @description: 过滤器
|
|
|
+ * @param {Mat} image
|
|
|
+ * @return {*}
|
|
|
+ */
|
|
|
+ bool InfineFilter::filter(cv::Mat image, std::shared_ptr<cnstream::CNInferObject>& object){
|
|
|
+ if(!getNight(image)) return true;
|
|
|
+
|
|
|
+ cv::Mat img = image.clone();
|
|
|
+ // 腐蚀
|
|
|
+ erode(img, img, cv::Mat());
|
|
|
+
|
|
|
+ cv::Rect rect = cv::Rect(object->bbox.x * image.cols,object->bbox.y * image.rows, object->bbox.w * image.cols, object->bbox.h * image.rows);
|
|
|
+ cv::Mat dst = img(rect);
|
|
|
+ cv::Mat imgThresholded;
|
|
|
+ // 转换为二值图
|
|
|
+ cv::inRange(dst, cv::Scalar(128, 128, 128), cv::Scalar(255, 255, 255), imgThresholded);
|
|
|
+ cv::threshold(imgThresholded, imgThresholded, 1, 255, cv::THRESH_BINARY);
|
|
|
+
|
|
|
+ // 寻找轮廓
|
|
|
+ vector<vector<cv::Point>> contours;
|
|
|
+ vector<cv::Vec4i> hierarchy;
|
|
|
+ cv::findContours(imgThresholded, contours, hierarchy, cv::RETR_TREE, cv::CHAIN_APPROX_SIMPLE);
|
|
|
+
|
|
|
+ if(contours.empty()) return true;
|
|
|
+ // 获取最大轮廓
|
|
|
+ double max_area = cv::contourArea(cv::InputArray(contours[0]), false);
|
|
|
+ for(unsigned long long i = 1; i < contours.size(); i++){
|
|
|
+ double temp_area = cv::contourArea(cv::InputArray(contours[i]), false);
|
|
|
+ if(max_area < temp_area){
|
|
|
+ max_area = temp_area;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ double b = max_area / (object->bbox.w * image.cols * object->bbox.h * image.rows);
|
|
|
+ // 计算轮廓比例
|
|
|
+ if(b > 0.5){
|
|
|
+ if(saveFilterResult){
|
|
|
+ cv::Point top_left;
|
|
|
+ cv::Point bottom_right;
|
|
|
+ top_left.x = object->bbox.x * image.cols;
|
|
|
+ top_left.y = object->bbox.y * image.rows;
|
|
|
+ bottom_right.x = top_left.x + (object->bbox.w * image.cols);
|
|
|
+ bottom_right.y = top_left.y + (object->bbox.h * image.rows);
|
|
|
+ cv::Point logo_pos(5, image.rows - 5);
|
|
|
+ cv::Scalar color(200, 200, 200);
|
|
|
+ cv::putText(img, std::to_string(b), logo_pos, 0, 1, color, 2);
|
|
|
+ cv::rectangle(img, top_left, bottom_right, cv::Scalar(0, 255, 0), 4);
|
|
|
+ if(opendir(this->files.c_str()) == NULL){
|
|
|
+ mkdir((this->files).c_str(),S_IRWXU|S_IRWXG|S_IRWXO);
|
|
|
+ }
|
|
|
+ cv::imwrite(this->files + getTime() + ".jpg", img);
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @description: 判断时间是否为晚上
|
|
|
+ * @param {*}
|
|
|
+ * @return {*}
|
|
|
+ */
|
|
|
+ bool InfineFilter::getNight(cv::Mat image){
|
|
|
+ time_t now = time(0);
|
|
|
+ tm *gmtm = gmtime(&now);
|
|
|
+ if(gmtm->tm_hour > this->start || gmtm->tm_hour < this->end){
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @description: 获取时间
|
|
|
+ * @param {*}
|
|
|
+ * @return {*}
|
|
|
+ */
|
|
|
+ std::string InfineFilter::getTime(){
|
|
|
+ std::string nowtime;
|
|
|
+ time_t rawtime;
|
|
|
+ char ctime[80];
|
|
|
+ struct tm *info;
|
|
|
+ time(&rawtime);
|
|
|
+ info = localtime(&rawtime);
|
|
|
+ strftime(ctime, 80, "%Y-%m-%d_%H:%M:%S", info);
|
|
|
+ nowtime = ctime;
|
|
|
+ return nowtime;
|
|
|
+ }
|
|
|
+};
|