此文在我的个人博客地址:https://sublimerui.top/archives/48ab4a6e.html

目录

  • 调试平台
  • 汽车识别原理——背景/前景分割算法
  • 整体结构
    • 整体流程框架图
    • 主要参数
    • 主要函数
  • 测试结果
  • 结论
  • 附:程序源代码

闲话少絮。开始正题——OpenCV的车流量统计。

调试平台

  • OpenCV 4.2
  • VS 2019

汽车识别原理——背景/前景分割算法

如今,检测和提取车辆时候,常用的方法有MOG2算法和KNN算法。MOG算法是以高斯混合模型(GMM)为基础的背景/前景分割算法。它是以2004年和2006年Z.Zivkovic的两篇文章为基础的。这个算法的一个特点是它为每一个像素选择一个合适数目的高斯分布。其主要原理为:在一个固定位置和角度固定的视频或图像中,提取分割图像或视频中运动的成分。此算法使用背景建模的方式,将整张图片或一帧视频分为前景和后景。此算法运行时,会将动态的前景与静止的后景相减,得出结果即为徐提取的运动物体的图像。

K最近邻算法(KNN)是属于机器学习的一种算法。其主要原理为:给定一个已训练数据集,对新的输入实例,在训练数据集中找到与该实例最邻近(注:衡量邻近的标准以具体选取的某个特征而言,例如下面示意图中使用的特征为欧式距离)的K个实例,这K个实例的多数属于某个类,则判定该输入实例同属此类。如下图所示:训练者取k值,计算以欧氏距离k为半径的圆内其他类别的个数,图中中心小红点以k为半径的圆内三角形个数最多,则判定中心小红点为三角形。

整体结构

整体流程框架图

本程序的主要运行流程为:程序运行开始,首先从文件中获取上次保存的光流量检测矩形框数据(顶点坐标和矩形的长宽);其后,分别初始化背景提取对象,使用MOG2和KNN两种算法。与此同时,建立一个鼠标回调函数,用于捕获鼠标左键(绘制矩形框)、中键(取消操作)和右键(保存矩形框数据到文件)的操作。

此后,程序进入主循环状态。程序循环从视频中获取一帧的图像,先进行压缩处理,以提高后续运算速度。之后,将这一帧图片从RGB转为灰度图片。为了祛除灰度后可能出现的小毛刺杂点,再进行平滑滤波处理。此后,分别通过MOG2和KNN算法提取前景,并将提取后的视频显示出来。与此同时,获取每个矩形框中积分后的亮度和。

最后,两个算法中,分别将实时得到的亮度和与所预设的阈值进行比较,当满足条件后,便认为一辆汽车通过矩形框,使得计数器加一。如此重复,统计整个视频中的车流量。

主要参数

  1. int detectTHD

此参数为预设的亮度阈值。确定是否有汽车经过检测框中,其需要联合上一帧积分亮度和本次积分亮度后综合做出决定。

  1. cv::Size newSize(frame.cols / 2, frame.rows / 2);

此参数可以储存一帧视频缩小后的大小。

  1. cv::Mat showMat;

此参数用于储存最终显示的图像矩阵。

主要函数

  1. static void onMouse(int event, int x, int y, int flags, void\*)

此函数主要用于检测鼠标左键、滑轮(中键)和右键的一些操作,用于绘制矩形检测框。

  1. cv::resize(frame, newframe, newSize);

此函数主要用于缩小原视频比例,提高计算机运算速度。

  1. bgMOG2-\>apply(greyFrame, mog2RES, update_bg_model ? -1 : 0);以及bgKNN-\>apply(greyFrame, KNN, update_bg_model ? -1 : 0);

apply函数主要用于两种算法的前景提取。此后,前景提取后的这帧视频保存于bgMOG2和bgKNN之中。

  1. cv::rectangle(showMat, myLanneRect.at(k), cv::Scalar(255, 255, 255), 3);

此函数主要用于前景提取后在其上面绘制矩形框。

  1. cv::integral(subMat, sumMat, CV_32S);

计算车道矩形框亮度积分图。

  1. cv::putText();

此函数可以按照要求,在视频图像上显示文字和统计数字。

测试结果

  1. 功能测试

进行车流量统计前,应当首先根据矩形框中出现车辆时,估算其亮度平均值作为亮度阈值,使其设定为一个较为合适的值,增强检测的灵敏性。由下图可知,当程序运行后,通过手动标记车道检测区域,得到2个矩形检测区。每次获得矩形中的积分亮度结果,当上从亮度结果大于阈值,且此次亮度结果小于阈值时,使车辆统计结果加一。

  1. 算法处理时间

由测试结果可知,相较于MOG2算法,KNN算法在运算处理上花费更多的时间,KNN算法时间约为MOG2时间的2倍。同时,算法处理总时间也相对较长,除了两个算法所带来的开销外,仍有其他附加代码所花费的时间。

  1. 缩放图片前后比较

程序中,可以使用cv::resize();函数进行图片的压缩,缩放图片对于检测速度有较大的影响。不使用缩放时,将视频中原始一帧的图像进行计算,经测试发现,处理速度很慢,显示的图片有明显的脱帧和卡顿现象,CPU占用率相当高,与压缩后(上图)相比,无论使用MOG2还是KNN算法,其处理时间均成倍增加。下图为不使用缩小图片尺寸条件下的处理时间。

  1. 矩形检测区亮度阈值的影响

阈值设置的合理性也是车流量检测准确性的一个重要指标。过高或过低的阈值均不能很好地反映车辆的经过和实现的统计。阈值过低,将会把视频中环境干扰噪声和其他运动对象(如三轮车和行人)当做汽车统计,使得统计结果偏大;同理,阈值过高,将很难检测到车辆的通过,当车辆进过矩形检测区时,无法实现车辆的统计。本程序中,经过检测矩形框内平均值的大致估算,将阈值detectTHD设置为900000。

下图中显示了当阈值设定过小时的状况。右端矩形框(右车道)经过了一辆电动车,程序误认为汽车,并错误地将统计结果L1的值从1加为2。

同理,当阈值设置过大,也会造成统计的不准确。下图显示了当阈值设定过大时的状况。可以发现,即使是车辆经过了矩形框,车辆统计变量L0和L1仍为0。

结论

由以上分析可知,汽车流量的统计可以借助设定矩形区域内的亮度阈值来确定。为识别运动对象(汽车)的状态,可使用背景提取算法,如本软件中使用到的MOG2和KNN算法。通过比较不同算法间的处理时间,我们应当合理选择一种耗时短且提取车辆准确性高的一种算法。此外,识别统计车流量较为重要的一环便是设置合理的亮度阈值,亮度阈值设置的合理性直接关系到车流量统计准确性。

附:程序源代码

此项目Github地址: https://github.com/cwxyr/traffic-detection

#include "stdafx.h"
#include <Windows.h>
#include <string>
#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/features2d.hpp>
#include <opencv2/video.hpp>#ifdef _DEBUG
#pragma comment(lib, "opencv_world420d.lib")
#else
#pragma comment(lib, "opencv_world420.lib")
#endif//===【鼠标事件回调函数】===
int detectTHD = 900000;        //亮度阈值:有车辆经过的;
std::vector<int>      myLanneLightSum_Last;           //车道亮度和:上一帧的
std::vector<int>      myLanneVihicleCnt;              //车道车辆计数器std::vector<cv::Rect>        myLanneRect;            //车道矩形框;显示为红色;
std::vector<cv::Point>        myMousePoints;      //鼠标点向量;显示为蓝色;
int myMouseEventBusy = 0;                          //鼠标回调事件忙:简单的资源锁
static void onMouse(int event, int x, int y, int flags, void*)
{myMouseEventBusy = 1;cv::Point  mPoint;cv::Rect mRect;switch (event){case cv::EVENT_LBUTTONDOWN:      //左键按下:增加myMousePoints中的点数mPoint = cv::Point(x, y);myMousePoints.push_back(mPoint);    //将当前鼠标点推送到向量中;if (myMousePoints.size() > 4)myMousePoints.erase(myMousePoints.begin());   //保证myMousePoints向量中节点数不大于4;break;case cv::EVENT_RBUTTONDOWN:        //右键键按下:将myMousePoints中的4个点推送到矩形框向量myLanneRectif (myMousePoints.size() == 4){int Xmin = 100000; int Ymin = 100000;int Xmax = 0; int Ymax = 0;for (int k = 0; k < 4; k++){Xmin = std::min(Xmin, myMousePoints.at(k).x);Ymin = std::min(Ymin, myMousePoints.at(k).y);Xmax = std::max(Xmax, myMousePoints.at(k).x);Ymax = std::max(Ymax, myMousePoints.at(k).y);}//for k   <<< === 用四个点构成矩形框的参数mRect = cv::Rect(Xmin, Ymin, Xmax - Xmin, Ymax - Ymin);     //构成矩形框myLanneRect.push_back(mRect);myLanneLightSum_Last.push_back(0);myLanneVihicleCnt.push_back(0);myMousePoints.clear();  //清除鼠标点向量}///ifbreak;case cv::EVENT_MBUTTONDOWN:       //中间键键按下:删除myMousePoints中的一个点;myMousePoints为空时,删除myLanneRect中的节点;printf("EVENT_MBUTTONDOWN\n");if (myMousePoints.size() > 0)myMousePoints.pop_back();else{myLanneRect.pop_back();myLanneLightSum_Last.pop_back();myLanneVihicleCnt.pop_back();}break;}/switch
myMouseEventBusy = 0;
return;
}int main(int argc, char* argv[])
{char errorMSG[256];char curPathName[384] = ""; char curModulerPath[384] = "";GetCurrentDirectory(383, curModulerPath); printf("Line39: curModulerPath = %s\n", curModulerPath);//=======读取标记的矩形框文件内容到myLanneRect:=======#ifndef READ_RECT_FILEFILE *pFILE = fopen("MarkRect.txt", "r");if (pFILE != NULL){cv::Rect  mRect;while (fgets(errorMSG, 255, pFILE) != NULL){int rtn = sscanf(errorMSG, "%d %d %d %d", &mRect.x, &mRect.y, &mRect.width, &mRect.height);if (rtn == 4) {myLanneRect.push_back(mRect);myLanneLightSum_Last.push_back(0);myLanneVihicleCnt.push_back(0);}}fclose(pFILE);}///if#endif // !READ_RECT_FILEstd::string  imgName = "video-02.mp4";char FilePath[384];if (strlen(curPathName) > 0)sprintf(FilePath, "%s\\%s", curPathName, imgName.c_str()); //图片文件路径elsesprintf(FilePath, "%s", imgName.c_str()); //图片文件路径//==【01】== 打开视频文件或摄像头cv::VideoCapture cap; //VideoCapture类实例化,使用缺省摄像头if (0 && "UsingCam")cap.open(0);elsecap.open(FilePath);if (!cap.isOpened()) // check if we succeeded{printf("error#73: 打开设备或文件失败,检查是否存在!回车退出!\n路径=%s\n", FilePath);fgets(FilePath, 127, stdin);return -1;}cv::Mat frame, newframe, greyFrame, floatFrame, lastFrame, frame2, mog2RES, KNN, out_frame, avgFrame;std::vector<cv::Mat> diffIMGvec;//==【02】== 创建运动视频背景提取对象:用于分离背景和运动对象cv::Ptr<cv::BackgroundSubtractorMOG2> bgMOG2 = cv::createBackgroundSubtractorMOG2();cv::Ptr<cv::BackgroundSubtractorKNN> bgKNN = cv::createBackgroundSubtractorKNN();bgMOG2->setVarThreshold(30);bool update_bg_model = true;//==【03】== 命名几个显示窗口cv::namedWindow("RawWnd", cv::WINDOW_NORMAL);cv::setMouseCallback("RawWnd", onMouse, &newframe);     //设置鼠标事件回调函数("RawWnd"窗口的):同时传递彩色图像指针;cv::namedWindow("Out_KNN", cv::WINDOW_NORMAL);cv::namedWindow("Out_MOG2", cv::WINDOW_NORMAL);int frameNums = 0;for (;;){frame.rows = 0;double t1 = (double)cv::getCPUTickCount();  //开始统计时间cap.read(frame);if (frame.rows == 0)break;cv::Size newSize(frame.cols / 2, frame.rows / 2);  //压缩图像,将其尺寸缩小cv::resize(frame, newframe, newSize);cv::cvtColor(newframe, greyFrame, cv::COLOR_RGB2GRAY);  //转换为灰度图cv::blur(greyFrame, greyFrame, cv::Size(3, 3));        //使用平滑运算double t2 = (double)cv::getCPUTickCount();bgMOG2->apply(greyFrame, mog2RES, update_bg_model ? -1 : 0);   //使用MOG2算法提取前景double t3 = (double)cv::getCPUTickCount();  //获取处理时间double t4 = (double)cv::getCPUTickCount();bgKNN->apply(greyFrame, KNN, update_bg_model ? -1 : 0);           //使用KNN算法提取前景double t5 = (double)cv::getCPUTickCount();  //获取处理时间printf("MOG2 Time = %.3fms\n", 1e0 * (t3 - t2) / (double)cv::getTickFrequency());printf("KNN Time = %.3fms\n", 1e0 * (t5 - t4) / (double)cv::getTickFrequency());printf("Total Time = %.3fms\n", 1e0 * (t5 - t1) / (double)cv::getTickFrequency());printf("--------------------\n");if (!mog2RES.empty())  //计算MOG2算法下矩形框的积分亮度值{cv::Mat showMat;mog2RES.copyTo(showMat);if (myMouseEventBusy == 0){for (int k = 0; k < myLanneRect.size(); k++){cv::rectangle(showMat, myLanneRect.at(k), cv::Scalar(255, 255, 255), 3);cv::Mat subMat = mog2RES(myLanneRect.at(k));  //再MOG2的前景提取结果中,取车道标记矩形框区域为subMat矩阵cv::Mat sumMat;       //积分图 == subMat的积分矩阵cv::integral(subMat, sumMat, CV_32S);     //设置积分矩阵的数据类型为uint;int sumValue = (int)sumMat.at<int>((int)sumMat.rows - 1, (int)sumMat.cols - 1);  //获取积分图右下角的值,就是矩形框内亮度和;sprintf(errorMSG, "sum = %d;", sumValue);cv::putText(showMat, errorMSG, cv::Point(myLanneRect.at(k).x, myLanneRect.at(k).y + 4), 0.2, 1, cv::Scalar(255, 0, 0), 2);//显示矩形框内的亮度和;}//for k}ifcv::imshow("Out_MOG2", showMat);}if (!KNN.empty())   //计算KNN算法下矩形框的积分亮度值{cv::Mat showMat;KNN.copyTo(showMat);if (myMouseEventBusy == 0){for (int k = 0; k < myLanneRect.size(); k++){cv::rectangle(showMat, myLanneRect.at(k), cv::Scalar(255, 255, 255), 3);cv::Mat subMat = KNN(myLanneRect.at(k));   //再KNN的前景提取结果中,取车道标记矩形框区域为subMat矩阵cv::Mat sumMat;        //积分图 == subMat的积分矩阵cv::integral(subMat, sumMat, CV_32S);     //设置积分矩阵的数据类型为uint;int sumValue = (int)sumMat.at<int>((int)sumMat.rows - 1, (int)sumMat.cols - 1);  //获取积分图右下角的值,就是矩形框内亮度和;sprintf(errorMSG, "sum = %d;", sumValue);cv::putText(showMat, errorMSG, cv::Point(myLanneRect.at(k).x, myLanneRect.at(k).y + 4), 0.2, 1, cv::Scalar(255, 0, 0), 2);//显示矩形框内的亮度和;}//for k}ifimshow("Out_KNN", showMat);}         //===>>> 显示原始图像:显示车道标记信息 + 矩形框内亮度和 + 车流量统计#ifndef SHOW_RAW_MATcv::Mat showMat;newframe.copyTo(showMat); //矩阵复制sprintf(errorMSG, "mL=add Point; mR=add Rect; mM=delete Point;");cv::putText(showMat, errorMSG, cv::Point(8, 32), 0.2, 1, cv::Scalar(255, 0, 0), 2);//显示提示信息;//==>> 显示车道矩形框为红色 + 车流量统计 + 车流量显示if (myMouseEventBusy == 0){for (int k = 0; k < myLanneRect.size(); k++){cv::rectangle(showMat, myLanneRect.at(k), cv::Scalar(0, 0, 255), 3);cv::Mat subMat = mog2RES(myLanneRect.at(k));    //再MOG2的前景提取结果中,取车道标记矩形框区域为subMat矩阵cv::Mat sumMat;       //积分图 == subMat的积分矩阵cv::integral(subMat, sumMat, CV_32S);     //设置积分矩阵的数据类型为int,计算车道矩形框内亮度积分图;int sumValue = (int)sumMat.at<int>((int)sumMat.rows - 1, (int)sumMat.cols - 1);  //获取积分图右下角的值,就是矩形框内亮度和;sprintf(errorMSG, "sum = %d;", sumValue);cv::putText(showMat, errorMSG, cv::Point(myLanneRect.at(k).x, myLanneRect.at(k).y + 4), 0.2, 1, cv::Scalar(255, 255, 0), 2);//显示矩形框内的亮度和;//===>>> 车流量统计:if (myLanneLightSum_Last.at(k) > detectTHD && sumValue <= detectTHD){//:: 车辆通过了矩形框:上一帧亮度和大于阈值,本帧亮度和小于阈值;车辆计数器自加;myLanneVihicleCnt.at(k)++;myLanneLightSum_Last.at(k) = sumValue;}else myLanneLightSum_Last.at(k) = sumValue;  //存储当前亮度和到myLanneLightSum_Last               }//for k//===>> 车流量统计结果显示cv::Mat topareaMat = showMat(cv::Rect(0, 0, showMat.cols, 75));      //最顶部48行置0;topareaMat *= 255;std::string strVihicleCnt = "VihicleCnt: ";for (int k = 0; k < myLanneRect.size(); k++){sprintf(errorMSG, "L%d = %d;", k, myLanneVihicleCnt.at(k));strVihicleCnt += errorMSG;}cv::putText(showMat, strVihicleCnt.c_str(), cv::Point(8, 64), 0.2, 1, cv::Scalar(0, 0, 255), 2); //流量统计显示到彩色图片上}if//==>> 显示正在标记的坐标点为蓝色:if (myMouseEventBusy == 0){for (int k = 1; k < myMousePoints.size(); k++){cv::line(showMat, myMousePoints.at(k - 1), myMousePoints.at(k), cv::Scalar(255, 0, 0), 15);}//for kif(myMousePoints.size() == 4)cv::line(showMat, myMousePoints.at(0), myMousePoints.at(3), cv::Scalar(255, 0, 0), 2);}ifimshow("RawWnd", showMat);#endif // SHOW_RAW_MATint keycode = cv::waitKey(100);      //等待100msif (keycode == 'q')break;else if (keycode == ' '){update_bg_model = !update_bg_model;printf("Learn background is in state = %d\n", update_bg_model);}else if (keycode == 'w'){//写文件:记录标记的矩形框到文件中:#ifndef WRITE_RECT_FILEFILE *pFILE = fopen("MarkRect.txt", "w");if (pFILE != NULL){for (int k = 0; k < myLanneRect.size(); k++) {fprintf(pFILE, "%d %d %d %d\n", myLanneRect.at(k).x, myLanneRect.at(k).y, myLanneRect.at(k).width, myLanneRect.at(k).height);}fclose(pFILE);}///if#endif // !WRITE_RECT_FILE}frameNums++;Sleep(50);}//for cap.release();return 0;
}

利用OpenCV实现对车流量的统计相关推荐

  1. 利用OpenCV、Python和Ubidots构建行人计数器程序(附完整代码)

    作者 | Jose Garcia 译者 | 吴振东 校对 | 张一豪.林亦霖,编辑 | 于腾凯 来源 | 数据派(ID:datapi) 导读:本文将利用OpenCV,Python和Ubidots来编写 ...

  2. 如何利用OpenCV寻找轮廓的中心?

    简 介: 本文介绍了利用OpenCV和Python编程来计算形状轮廓的中心点.当然后面还会继续给出如何通过轮廓来分辨物体形状种类,以及对于各自的颜色进行标准. 关键词: OpenCV,contours ...

  3. python中import cv2遇到的错误及安装方法_独家利用OpenCV,Python和Ubidots来构建行人计数器程序(附代码amp;解析)...

    作者:Jose Garcia 翻译:吴振东 校对:张一豪 本文约4000字,建议阅读14分钟. 本文将利用OpenCV,Python和Ubidots来编写一个行人计数器程序,并对代码进行了较为详细的讲 ...

  4. python用opencv计算汽车间距_计算机视觉:利用OpenCV和Python进行车辆计数详细步调...

    本教程我将分享几个简单步调剂释如何使用OpenCV进行Python对象计数. 需要安装一些软件: Python 3OpennCV 1.了解Opencv从摄像头获得视频的Python脚本 import ...

  5. python如何实现找图_利用OpenCV和Python实现查找图片差异

    使用OpenCV和Python查找图片差异 flyfish 方法1 均方误差的算法(Mean Squared Error , MSE) 下面的一些表达与<TensorFlow - 协方差矩阵&g ...

  6. 利用OpenCV识别玻璃纤维织物劈缝缺陷

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 玻璃纤维织物是经编多轴向织物,由一层或多层平行的纱线按照尽可能多的 ...

  7. opencv resize_利用OpenCV 识别两张相似的图片

    Background: 在我们项目中,用到U-net,我们对训练样本图片使用labelme进行标定,对标定生成的json文件labelme_json_to_dataset生成标注图像,由于小伙伴将生成 ...

  8. 独家|OpenCV1.9 如何利用OpenCV的parallel_for_并行化代码(附代码)

    翻译:陈之炎 校对:顾伟嵩本文约3200字,建议阅读7分钟本教程的目标是展示如何使用OpenCV的parallel_for_框架轻松实现代码并行化. 目标 本教程的目标是展示如何使用OpenCV的pa ...

  9. opencv 取roi_利用OpenCV 识别两张相似的图片

    Background: 在我们项目中,用到U-net,我们对训练样本图片使用labelme进行标定,对标定生成的json文件labelme_json_to_dataset生成标注图像,由于小伙伴将生成 ...

  10. 利用OpenCV读取和写入视频

    简 介: 本文介绍了如何对三种不同的视频源(视频文件, 序列图片以及网络摄像头)来进行读取显示视频,使用视频捕获对象. 也给出了如何通过视频捕获对象获取视频流的重要元数据. 介绍了使用视频写入对象把视 ...

最新文章

  1. 针对七牛含有特殊字符的文件名,对特殊字符编码处理
  2. cocos2d+lua实现帧动画播放
  3. sed 格式化输出df -h
  4. 37镇魔曲网页版服务器状态,37镇魔曲网页版各职业攻略分析
  5. js/jquery判断浏览器 停止加载
  6. 全志 添加外挂RTC Hym8563
  7. qaxobject控制word到某一行_Word操作技巧:快速选择文本的4种技能,提高你的工作效率...
  8. python list遍历定位元素_python for循环,第二遍定位不到元素?
  9. 华为Mate 40 Pro概念渲染图曝光:首发屏下摄像头技术?
  10. 三层交换和二层交换之间的端口聚合
  11. datagridview列 值提取_提取符合条件的多个记录,VLOOKUP:盘他!
  12. Halcon缺陷检测——机器学习1
  13. maple软件安装教程
  14. linux-ubuntu-obs推流到bilibili及虎牙直播测试
  15. windows无法完成格式化U盘的几种终极解决办法
  16. mysql数据导出insert_mysql 数据导出
  17. bat脚本——提取多个文件夹到指定路径
  18. JavaScript数组some方法
  19. 当老板让程序员换灯泡…… | 每日趣闻
  20. 【思考】人脸认证真的准确吗?通过身份证的人脸对比有哪些问题?

热门文章

  1. 浅谈管理软件的功能与作用-—以Nvisual综合布线可视化运维管理平台和进销存管理软件为例
  2. jQuery EasyUI快速入门01
  3. wincc版本升级_wincc组态软件下载
  4. cad立面索引符号 规范_园林景观设计规范——园林人都该知道!
  5. win10设置HTML桌面背景,Win10系统直接将视频设置为桌面背景的方法
  6. appinfo.json
  7. 三方演化博弈复制动态方程matlab仿真(输入参数较多时)——matlab2016a版本
  8. 《数字电子技术基础》4.3 若干常用的组合逻辑电路 学习笔记
  9. 淘宝客商城带分销APP源码(原生双端IOS+安卓+后台+数据 库+开发文档),用于学习或二开使用,开发语言:安卓java,苹果oc,后台php。
  10. 计算机网络推荐,计算机网络 | CCF推荐 | 国际会议信息4条