基于QT的opencv插件框架qtCvFrameLearn实战

简介: 这篇文章详细介绍了如何基于Qt框架开发一个名为qtCvFrameLearn的OpenCV插件,包括项目配置、插件加载、Qt与OpenCV图像转换,以及通过各个插件学习OpenCV函数的使用,如仿射变换、卡通效果、腐蚀、旋转和锐化等。

0 结果展示

github项目链接: 基于QT的opencv插件框架qtCvFrameLearn.
csdn文章:基于QT的opencv插件框架qtCvFrameLearn.
基于QT的opencv插件框架qtCvFrameLearn

1 参考链接

链接: 本文微信文章,更多讲解.
链接: Qt-5-and-OpenCV-4-Computer-Vision-Projects.
链接: qt5.13配置opencv4.2环境 mscv版.

2 文件目录结构

qt插件框架qtCvFrameLearnqt插件框架qtCvFrameLearn

3 项目配置文件ImageEditor.pro

######################################################################
# Automatically generated by qmake (3.1) Sun Nov 11 20:07:20 2018
######################################################################


TEMPLATE = app
TARGET = ImageEditor
DESTDIR = ../App

QT += core gui network
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

## use your own path in the following config
#unix: !mac {
   
#    INCLUDEPATH += /home/kdr2/programs/opencv/include/opencv4
#    LIBS += -L/home/kdr2/programs/opencv/lib -lopencv_core -l opencv_imgproc
#}

#unix: mac {
   
#    INCLUDEPATH += /path/to/opencv/include/opencv4
#    LIBS += -L/path/to/opencv/lib -lopencv_world
#}

#win32 {
   
##    INCLUDEPATH += c:/path/to/opencv/include/opencv4
##    LIBS += -lc:/path/to/opencv/lib/opencv_world
#    INCLUDEPATH += C:/opencv451/include/opencv2
##    LIBS += -lC:/opencv451/vc15/opencv_world
#}

# The following define makes your compiler warn you if you use any
# feature of Qt which has been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

# Input
HEADERS += mainwindow.h editor_plugin_interface.h
SOURCES += main.cpp mainwindow.cpp

# opencv config
INCLUDEPATH += C:/opencv451/include
DEPENDPATH += C:/opencv451/include

win32:CONFIG(release, debug|release): LIBS += -LC:/opencv451/vc15/lib/ \
opencv_aruco451.lib  \
opencv_bgsegm451.lib  \
opencv_bioinspired451.lib  \
opencv_ccalib451.lib  \
opencv_core451.lib  \
opencv_cudaarithm451.lib  \
opencv_cudabgsegm451.lib  \
opencv_cudacodec451.lib  \
opencv_cudafilters451.lib  \
opencv_cudaimgproc451.lib  \
opencv_cudalegacy451.lib  \
opencv_cudaobjdetect451.lib  \
opencv_cudaoptflow451.lib  \
opencv_cudastereo451.lib  \
opencv_cudawarping451.lib  \
opencv_cudev451.lib  \
opencv_cvv451.lib  \
opencv_datasets451.lib  \
opencv_dnn451.lib  \
opencv_dpm451.lib  \
opencv_face451.lib  \
opencv_flann451.lib  \
opencv_fuzzy451.lib  \
opencv_gapi451.lib  \
opencv_hfs451.lib  \
opencv_highgui451.lib  \
opencv_imgcodecs451.lib  \
opencv_imgproc451.lib  \
opencv_mcc451.lib  \
opencv_ml451.lib  \
opencv_objdetect451.lib  \
opencv_optflow451.lib  \
opencv_photo451.lib  \
opencv_plot451.lib  \
opencv_quality451.lib  \
opencv_rapid451.lib  \
opencv_reg451.lib  \
opencv_rgbd451.lib  \
opencv_saliency451.lib  \
opencv_shape451.lib  \
opencv_stereo451.lib  \
opencv_stitching451.lib  \
opencv_superres451.lib  \
opencv_text451.lib  \
opencv_tracking451.lib  \
opencv_video451.lib  \
opencv_videoio451.lib  \
opencv_videostab451.lib  \
opencv_ximgproc451.lib  \
opencv_xobjdetect451.lib  \
opencv_xphoto451.lib
else:win32:CONFIG(debug, debug|release): LIBS += -LC:/opencv451/vc15/lib/  \
opencv_aruco451d.lib  \
opencv_bgsegm451d.lib  \
opencv_bioinspired451d.lib  \
opencv_ccalib451d.lib  \
opencv_core451d.lib  \
opencv_cudaarithm451d.lib  \
opencv_cudabgsegm451d.lib  \
opencv_cudacodec451d.lib  \
opencv_cudafilters451d.lib  \
opencv_cudaimgproc451d.lib  \
opencv_cudalegacy451d.lib  \
opencv_cudaobjdetect451d.lib  \
opencv_cudaoptflow451d.lib  \
opencv_cudastereo451d.lib  \
opencv_cudawarping451d.lib  \
opencv_cudev451d.lib  \
opencv_cvv451d.lib  \
opencv_datasets451d.lib  \
opencv_dnn451d.lib  \
opencv_dpm451d.lib  \
opencv_face451d.lib  \
opencv_flann451d.lib  \
opencv_fuzzy451d.lib  \
opencv_gapi451d.lib  \
opencv_hfs451d.lib  \
opencv_highgui451d.lib  \
opencv_imgcodecs451d.lib  \
opencv_imgproc451d.lib  \
opencv_mcc451d.lib  \
opencv_ml451d.lib  \
opencv_objdetect451d.lib  \
opencv_optflow451d.lib  \
opencv_photo451d.lib  \
opencv_plot451d.lib  \
opencv_quality451d.lib  \
opencv_rapid451d.lib  \
opencv_reg451d.lib  \
opencv_rgbd451d.lib  \
opencv_saliency451d.lib  \
opencv_shape451d.lib  \
opencv_stereo451d.lib  \
opencv_stitching451d.lib  \
opencv_superres451d.lib  \
opencv_text451d.lib  \
opencv_tracking451d.lib  \
opencv_video451d.lib  \
opencv_videoio451d.lib  \
opencv_videostab451d.lib  \
opencv_ximgproc451d.lib  \
opencv_xobjdetect451d.lib  \
opencv_xphoto451d.lib
else:unix:!macx: LIBS += -LC:/opencv451/vc15/lib/ -lopencv_core451 \
-lopencv_*451

DISTFILES += \
    plugins/.gitkeep \
    plugins/AffinePlugin.dll \
    plugins/CartoonPlugin.dll \
    plugins/ErodePlugin.dll \
    plugins/RotatePlugin.dll \
    plugins/SharpenPlugin.dll

4 项目配置文件AffinePlugin.pro

######################################################################
# Automatically generated by qmake (3.1) Fri Nov 30 20:56:01 2018
######################################################################
#QT       += widgets

TARGET = AffinePlugin
TEMPLATE = lib
DESTDIR = ../App/plugins
INCLUDEPATH +=../ImageEditor


## use your own path in the following config
#unix: !mac {
   
#    INCLUDEPATH += /home/kdr2/programs/opencv/include/opencv4
#    LIBS += -L/home/kdr2/programs/opencv/lib -lopencv_core -l opencv_imgproc
#}

#unix: mac {
   
#    INCLUDEPATH += /path/to/opencv/include/opencv4
#    LIBS += -L/path/to/opencv/lib -lopencv_world
#}

#win32 {
   
#    INCLUDEPATH += C:/opencv451/include
#    LIBS += -lC:/opencv451/vc15/lib/ \
#            -lopencv_core451d
#            -lopencv_imgproc451d
#}

# The following define makes your compiler warn you if you use any
# feature of Qt which has been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

# Input
HEADERS += affine_plugin.h
SOURCES += affine_plugin.cpp


# opencv config
INCLUDEPATH += C:/opencv451/include
DEPENDPATH += C:/opencv451/include

win32:CONFIG(release, debug|release): LIBS += -LC:/opencv451/vc15/lib/ \
opencv_aruco451.lib  \
opencv_bgsegm451.lib  \
opencv_bioinspired451.lib  \
opencv_ccalib451.lib  \
opencv_core451.lib  \
opencv_cudaarithm451.lib  \
opencv_cudabgsegm451.lib  \
opencv_cudacodec451.lib  \
opencv_cudafilters451.lib  \
opencv_cudaimgproc451.lib  \
opencv_cudalegacy451.lib  \
opencv_cudaobjdetect451.lib  \
opencv_cudaoptflow451.lib  \
opencv_cudastereo451.lib  \
opencv_cudawarping451.lib  \
opencv_cudev451.lib  \
opencv_cvv451.lib  \
opencv_datasets451.lib  \
opencv_dnn451.lib  \
opencv_dpm451.lib  \
opencv_face451.lib  \
opencv_flann451.lib  \
opencv_fuzzy451.lib  \
opencv_gapi451.lib  \
opencv_hfs451.lib  \
opencv_highgui451.lib  \
opencv_imgcodecs451.lib  \
opencv_imgproc451.lib  \
opencv_mcc451.lib  \
opencv_ml451.lib  \
opencv_objdetect451.lib  \
opencv_optflow451.lib  \
opencv_photo451.lib  \
opencv_plot451.lib  \
opencv_quality451.lib  \
opencv_rapid451.lib  \
opencv_reg451.lib  \
opencv_rgbd451.lib  \
opencv_saliency451.lib  \
opencv_shape451.lib  \
opencv_stereo451.lib  \
opencv_stitching451.lib  \
opencv_superres451.lib  \
opencv_text451.lib  \
opencv_tracking451.lib  \
opencv_video451.lib  \
opencv_videoio451.lib  \
opencv_videostab451.lib  \
opencv_ximgproc451.lib  \
opencv_xobjdetect451.lib  \
opencv_xphoto451.lib
else:win32:CONFIG(debug, debug|release): LIBS += -LC:/opencv451/vc15/lib/  \
opencv_aruco451d.lib  \
opencv_bgsegm451d.lib  \
opencv_bioinspired451d.lib  \
opencv_ccalib451d.lib  \
opencv_core451d.lib  \
opencv_cudaarithm451d.lib  \
opencv_cudabgsegm451d.lib  \
opencv_cudacodec451d.lib  \
opencv_cudafilters451d.lib  \
opencv_cudaimgproc451d.lib  \
opencv_cudalegacy451d.lib  \
opencv_cudaobjdetect451d.lib  \
opencv_cudaoptflow451d.lib  \
opencv_cudastereo451d.lib  \
opencv_cudawarping451d.lib  \
opencv_cudev451d.lib  \
opencv_cvv451d.lib  \
opencv_datasets451d.lib  \
opencv_dnn451d.lib  \
opencv_dpm451d.lib  \
opencv_face451d.lib  \
opencv_flann451d.lib  \
opencv_fuzzy451d.lib  \
opencv_gapi451d.lib  \
opencv_hfs451d.lib  \
opencv_highgui451d.lib  \
opencv_imgcodecs451d.lib  \
opencv_imgproc451d.lib  \
opencv_mcc451d.lib  \
opencv_ml451d.lib  \
opencv_objdetect451d.lib  \
opencv_optflow451d.lib  \
opencv_photo451d.lib  \
opencv_plot451d.lib  \
opencv_quality451d.lib  \
opencv_rapid451d.lib  \
opencv_reg451d.lib  \
opencv_rgbd451d.lib  \
opencv_saliency451d.lib  \
opencv_shape451d.lib  \
opencv_stereo451d.lib  \
opencv_stitching451d.lib  \
opencv_superres451d.lib  \
opencv_text451d.lib  \
opencv_tracking451d.lib  \
opencv_video451d.lib  \
opencv_videoio451d.lib  \
opencv_videostab451d.lib  \
opencv_ximgproc451d.lib  \
opencv_xobjdetect451d.lib  \
opencv_xphoto451d.lib
else:unix:!macx: LIBS += -LC:/opencv451/vc15/lib/ -lopencv_core451 \
-lopencv_*451

5 代码梳理

5.1 插件加载

void MainWindow::loadPlugins()
{
   
    QDir pluginsDir(QApplication::instance()->applicationDirPath() + "/plugins");
    QStringList nameFilters;
    nameFilters << "*.so" << "*.dylib" << "*.dll";
    QFileInfoList plugins = pluginsDir.entryInfoList(
        nameFilters, QDir::NoDotAndDotDot | QDir::Files, QDir::Name);
    foreach(QFileInfo plugin, plugins) {
   
        QPluginLoader pluginLoader(plugin.absoluteFilePath(), this);
        EditorPluginInterface *plugin_ptr = dynamic_cast<EditorPluginInterface*>(pluginLoader.instance());
        if(plugin_ptr) {
   
            QAction *action = new QAction(plugin_ptr->name());
            editMenu->addAction(action);
            editToolBar->addAction(action);
            editPlugins[plugin_ptr->name()] = plugin_ptr;
            connect(action, SIGNAL(triggered(bool)), this, SLOT(pluginPerform()));
            // pluginLoader.unload();
        } else {
   
            qDebug() << "bad plugin: " << plugin.absoluteFilePath();
        }
    }
}

5.2 qt图像与opencv图像转换

void MainWindow::pluginPerform()
{
   
    if (currentImage == nullptr) {
   
        QMessageBox::information(this, "Information", "No image to edit.");
        return;
    }

    QAction *active_action = qobject_cast<QAction*>(sender());
    EditorPluginInterface *plugin_ptr = editPlugins[active_action->text()];
    if(!plugin_ptr) {
   
        QMessageBox::information(this, "Information", "No plugin is found.");
        return;
    }

    QPixmap pixmap = currentImage->pixmap();
    QImage image = pixmap.toImage();
    image = image.convertToFormat(QImage::Format_RGB888);
    cv::Mat mat = cv::Mat(
        image.height(),
        image.width(),
        CV_8UC3,
        image.bits(),
        image.bytesPerLine());

    plugin_ptr->edit(mat, mat);

    QImage image_edited(
        mat.data,
        mat.cols,
        mat.rows,
        mat.step,
        QImage::Format_RGB888);
    pixmap = QPixmap::fromImage(image_edited);
    imageScene->clear();
    imageView->resetMatrix();
    currentImage = imageScene->addPixmap(pixmap);
    imageScene->update();
    imageView->setSceneRect(pixmap.rect());
    QString status = QString("(editted image), %1x%2")
        .arg(pixmap.width()).arg(pixmap.height());
    mainStatusLabel->setText(status);
}

5.3 各个插件中的opencv函数学习

opencv中的Mat()函数

5.3.1 affine_plugin

// affine_plugin
void AffinePlugin::edit(const cv::Mat &input, cv::Mat &output)
{
   

    cv::Point2f triangleA[3];
    cv::Point2f triangleB[3];

    triangleA[0] = cv::Point2f(0 , 0);
    triangleA[1] = cv::Point2f(1 , 0);
    triangleA[2] = cv::Point2f(0 , 1);

    triangleB[0] = cv::Point2f(0, 0);
    triangleB[1] = cv::Point2f(1, 0);
    triangleB[2] = cv::Point2f(1, 1);

    cv::Mat affineMatrix = cv::getAffineTransform(triangleA, triangleB);
    cv::Mat result;
    cv::warpAffine(
        input, result,
        affineMatrix, input.size(), // output image size, same as input
        cv::INTER_CUBIC, // Interpolation method
        cv::BORDER_CONSTANT  // Extrapolation method
        //BORDER_WRAP  // Extrapolation method
    );

    output = result;
}
getAffineTransform
CV_EXPORTS_W Mat getAffineTransform( InputArray src, InputArray dst );

opencv中的getAffineTransform()函数

warpAffine
CV_EXPORTS_W void warpAffine( InputArray src, OutputArray dst,
                              InputArray M, Size dsize,
                              int flags = INTER_LINEAR,
                              int borderMode = BORDER_CONSTANT,
                              const Scalar& borderValue = Scalar());

opencv中的warpAffine()函数

5.3.2 cartoon_plugin

// cartoon_plugin
void CartoonPlugin::edit(const cv::Mat &input, cv::Mat &output)
{
   
    int num_down = 2;
    int num_bilateral = 7;

    cv::Mat copy1, copy2;
    cv::Mat image_gray, image_edge;

    copy1 = input.clone();
    for(int i = 0; i < num_down; i++) {
   
        cv::pyrDown(copy1, copy2);
        copy1 = copy2.clone();
    }

    for(int i = 0; i < num_bilateral; i++) {
   
        cv::bilateralFilter(copy1, copy2, 9, 9, 7);
        copy1 = copy2.clone();
    }

    for(int i = 0; i < num_down; i++) {
   
        cv::pyrUp(copy1, copy2);
        copy1 = copy2.clone();
    }

    if (input.cols != copy1.cols  || input.rows != copy1.rows) {
   
        cv::Rect rect(0, 0, input.cols, input.rows);
        copy1(rect).copyTo(copy2);
        copy1 = copy2;
    }

    cv::cvtColor(input, image_gray, cv::COLOR_RGB2GRAY);
    cv::medianBlur(image_gray, image_gray, 5);

    cv::adaptiveThreshold(image_gray, image_gray, 255,
        cv::ADAPTIVE_THRESH_MEAN_C, cv::THRESH_BINARY, 9, 2);

    cv::cvtColor(image_gray, image_edge, cv::COLOR_GRAY2RGB);

    output = copy1 & image_edge;

    /*
    cv::GaussianBlur(image_edge, image_edge, cv::Size(5, 5), 0);
    cv::Mat mask(input.rows, input.cols, CV_8UC3, cv::Scalar(90, 90, 90));
    mask = mask & (~image_edge);
    output = (copy1 & image_edge) | mask;
    */
}
pyrDown
CV_EXPORTS_W void pyrDown( InputArray src, OutputArray dst,
                           const Size& dstsize = Size(), int borderType = BORDER_DEFAULT );

opencv中的pyrDown()函数

bilateralFilter
CV_EXPORTS_W void bilateralFilter( InputArray src, OutputArray dst, int d,
                                   double sigmaColor, double sigmaSpace,
                                   int borderType = BORDER_DEFAULT );

opencv中的bilateralFilter()函数

pyrUp
CV_EXPORTS_W void pyrUp( InputArray src, OutputArray dst,
                         const Size& dstsize = Size(), int borderType = BORDER_DEFAULT );

opencv中的pyrUp()函数

medianBlur
CV_EXPORTS_W void medianBlur( InputArray src, OutputArray dst, int ksize );

opencv中的medianBlur()函数

adaptiveThreshold
CV_EXPORTS_W void adaptiveThreshold( InputArray src, OutputArray dst,
                                     double maxValue, int adaptiveMethod,
                                     int thresholdType, int blockSize, double C );

opencv中的adaptiveThreshold()函数

5.3.3 erode_plugin

void ErodePlugin::edit(const cv::Mat &input, cv::Mat &output)
{
   
    erode(input, output, cv::Mat());
}
erode
CV_EXPORTS_W void erode( InputArray src, OutputArray dst, InputArray kernel,
                         Point anchor = Point(-1,-1), int iterations = 1,
                         int borderType = BORDER_CONSTANT,
                         const Scalar& borderValue = morphologyDefaultBorderValue() );

opencv中的erode()函数

5.3.4 rotate_plugin

void RotatePlugin::edit(const cv::Mat &input, cv::Mat &output)
{
   
    double angle = 45.0;
    double scale = 1.0;
    cv::Point2f center = cv::Point(input.cols/2, input.rows/2);
    cv::Mat rotateMatrix = cv::getRotationMatrix2D(center, angle, scale);

    cv::Mat result;
    cv::warpAffine(input, result,
        rotateMatrix, input.size(),
        cv::INTER_LINEAR, cv::BORDER_CONSTANT);
    output = result;
}
getRotationMatrix2D
CV_EXPORTS Matx23d getRotationMatrix2D_(Point2f center, double angle, double scale);

inline
Mat getRotationMatrix2D(Point2f center, double angle, double scale)
{
   
    return Mat(getRotationMatrix2D_(center, angle, scale), true);
}

opencv中的getRotationMatrix2D()函数

5.3.5 sharpen_plugin

void SharpenPlugin::edit(const cv::Mat &input, cv::Mat &output)
{
   
    int intensity = 2;
    cv::Mat smoothed;
    cv::GaussianBlur(input, smoothed, cv::Size(9, 9), 0);
    output = input + (input - smoothed) * intensity;
}
GaussianBlur
CV_EXPORTS_W void GaussianBlur( InputArray src, OutputArray dst, Size ksize,
                                double sigmaX, double sigmaY = 0,
                                int borderType = BORDER_DEFAULT );

opencv中的GaussianBlur()函数

相关文章
|
11天前
|
弹性计算 人工智能 架构师
阿里云携手Altair共拓云上工业仿真新机遇
2024年9月12日,「2024 Altair 技术大会杭州站」成功召开,阿里云弹性计算产品运营与生态负责人何川,与Altair中国技术总监赵阳在会上联合发布了最新的“云上CAE一体机”。
阿里云携手Altair共拓云上工业仿真新机遇
|
8天前
|
机器学习/深度学习 算法 大数据
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析
2024“华为杯”数学建模竞赛,对ABCDEF每个题进行详细的分析,涵盖风电场功率优化、WLAN网络吞吐量、磁性元件损耗建模、地理环境问题、高速公路应急车道启用和X射线脉冲星建模等多领域问题,解析了问题类型、专业和技能的需要。
2522 17
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析
|
7天前
|
机器学习/深度学习 算法 数据可视化
【BetterBench博士】2024年中国研究生数学建模竞赛 C题:数据驱动下磁性元件的磁芯损耗建模 问题分析、数学模型、python 代码
2024年中国研究生数学建模竞赛C题聚焦磁性元件磁芯损耗建模。题目背景介绍了电能变换技术的发展与应用,强调磁性元件在功率变换器中的重要性。磁芯损耗受多种因素影响,现有模型难以精确预测。题目要求通过数据分析建立高精度磁芯损耗模型。具体任务包括励磁波形分类、修正斯坦麦茨方程、分析影响因素、构建预测模型及优化设计条件。涉及数据预处理、特征提取、机器学习及优化算法等技术。适合电气、材料、计算机等多个专业学生参与。
1522 15
【BetterBench博士】2024年中国研究生数学建模竞赛 C题:数据驱动下磁性元件的磁芯损耗建模 问题分析、数学模型、python 代码
|
3天前
|
存储 关系型数据库 分布式数据库
GraphRAG:基于PolarDB+通义千问+LangChain的知识图谱+大模型最佳实践
本文介绍了如何使用PolarDB、通义千问和LangChain搭建GraphRAG系统,结合知识图谱和向量检索提升问答质量。通过实例展示了单独使用向量检索和图检索的局限性,并通过图+向量联合搜索增强了问答准确性。PolarDB支持AGE图引擎和pgvector插件,实现图数据和向量数据的统一存储与检索,提升了RAG系统的性能和效果。
|
10天前
|
编解码 JSON 自然语言处理
通义千问重磅开源Qwen2.5,性能超越Llama
击败Meta,阿里Qwen2.5再登全球开源大模型王座
581 14
|
1月前
|
运维 Cloud Native Devops
一线实战:运维人少,我们从 0 到 1 实践 DevOps 和云原生
上海经证科技有限公司为有效推进软件项目管理和开发工作,选择了阿里云云效作为 DevOps 解决方案。通过云效,实现了从 0 开始,到现在近百个微服务、数百条流水线与应用交付的全面覆盖,有效支撑了敏捷开发流程。
19283 30
|
10天前
|
人工智能 自动驾驶 机器人
吴泳铭:AI最大的想象力不在手机屏幕,而是改变物理世界
过去22个月,AI发展速度超过任何历史时期,但我们依然还处于AGI变革的早期。生成式AI最大的想象力,绝不是在手机屏幕上做一两个新的超级app,而是接管数字世界,改变物理世界。
484 49
吴泳铭:AI最大的想象力不在手机屏幕,而是改变物理世界
|
1月前
|
人工智能 自然语言处理 搜索推荐
阿里云Elasticsearch AI搜索实践
本文介绍了阿里云 Elasticsearch 在AI 搜索方面的技术实践与探索。
18841 20
|
1月前
|
Rust Apache 对象存储
Apache Paimon V0.9最新进展
Apache Paimon V0.9 版本即将发布,此版本带来了多项新特性并解决了关键挑战。Paimon自2022年从Flink社区诞生以来迅速成长,已成为Apache顶级项目,并广泛应用于阿里集团内外的多家企业。
17530 13
Apache Paimon V0.9最新进展
|
2天前
|
云安全 存储 运维
叮咚!您有一份六大必做安全操作清单,请查收
云安全态势管理(CSPM)开启免费试用
365 4
叮咚!您有一份六大必做安全操作清单,请查收