Python OpenCV图像处理与深度学习:Python OpenCV性能优化与高效图像处理

OpenCV性能优化实战

学习目标

本课程将深入探讨如何通过多线程和NPU加速等技术优化OpenCV程序的性能,提高图像处理的速度和效率。通过本课程的学习,学员将能够掌握提升OpenCV应用性能的关键技术,使图像处理程序更加高效。

相关知识点

  • OpenCV性能优化

学习内容

1 OpenCV性能优化

1.1 多线程在OpenCV中的应用

在图像处理领域,多线程技术可以显著提高程序的执行效率,尤其是在处理大量图像数据时。OpenCV提供了多种方法来实现多线程处理,包括使用C++标准库中的std::thread和OpenCV自身的并行处理框架。

多线程技术的基本原理是将一个任务分解成多个子任务,每个子任务由一个独立的线程执行。这样可以充分利用多核处理器的计算能力,提高程序的执行效率。在OpenCV中,可以使用std::thread来创建和管理线程,也可以使用OpenCV的并行处理框架cv::parallel_for_来简化多线程编程。

下面是一个使用std::thread处理图像的简单示例:

c++ 复制代码
#include <opencv2/opencv.hpp>
#include <thread>
#include <vector>

void processImage(const cv::Mat& img, cv::Mat& result, int startRow, int endRow) {
    for (int i = startRow; i < endRow; ++i) {
        for (int j = 0; j < img.cols; ++j) {
            result.at<uchar>(i, j) = 255 - img.at<uchar>(i, j); // 简单的图像反转
        }
    }
}

int main() {
    cv::Mat img = cv::imread("input.jpg", cv::IMREAD_GRAYSCALE);
    if (img.empty()) {
        std::cerr << "Could not open or find the image" << std::endl;
        return -1;
    }

    cv::Mat result = cv::Mat::zeros(img.size(), img.type());

    int numThreads = 4;
    std::vector<std::thread> threads;
    int rowsPerThread = img.rows / numThreads;

    for (int i = 0; i < numThreads; ++i) {
        int startRow = i * rowsPerThread;
        int endRow = (i == numThreads - 1) ? img.rows : (i + 1) * rowsPerThread;
        threads.emplace_back(processImage, std::ref(img), std::ref(result), startRow, endRow);
    }

    for (auto& t : threads) {
        t.join();
    }

    cv::imwrite("output.jpg", result);
    return 0;
}

input.jpg:

将以上代码复制粘贴到main2.cpp中,然后运行(需要提前安装好g++/opencv等)

bash 复制代码
g++ main2.cpp -o mycpp2 `pkg-config --cflags --libs opencv4`

output.jpg:

1.2 NPU加速技术

昇腾NPU(神经网络处理单元)在图像处理和计算机视觉任务中具有显著优势,其架构专为深度学习和大规模并行计算设计,能够高效处理大量数据。OpenCV可通过与昇腾NPU相关的接口和框架来利用NPU加速图像处理。

与GPU类似,NPU加速的原理是将计算任务从CPU转移到NPU,借助NPU的并行计算能力加速处理。但NPU在架构和优化方向上更贴合深度学习等特定计算任务,能更高效地执行与图像处理相关的深度学习模型推理等操作。

昇腾NPU(神经网络处理单元)是专为深度学习和大规模并行计算设计的硬件加速器。其架构特点包括:

  • 高并行性:NPU拥有大量的计算核心,能够同时处理多个数据流,显著提高计算效率。
  • 专用指令集:NPU针对深度学习任务优化了指令集,能够更高效地执行卷积、矩阵运算等操作。
  • 内存优化:NPU配备了高带宽内存(HBM),减少了数据传输的延迟和能耗。

OpenCV 当前支持 20+ 昇腾算子,此处根据图像处理应用场景,选取 add, rotate 和 flip 算子的应用作示例代码。

c++ 复制代码
#include <iostream>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/cann.hpp>
#include <opencv2/cann_interface.hpp>

int main(int argc, char* argv[])
{
    cv::CommandLineParser parser(argc, argv,
    "{@input|puppy.png|path to input image}"
    "{@output|output.png|path to output image}"
    "{help||show help}");
    parser.about("This is a sample for image processing with Ascend NPU. \n");
    if (argc != 3 || parser.has("help"))
    {
        parser.printMessage();
        return 0;
    }

    std::string imagePath = parser.get<std::string>(0);
    std::string outputPath = parser.get<std::string>(1);

    // 读取输入图像
    cv::Mat img = cv::imread(imagePath);
    // 生成高斯噪声
    cv::Mat gaussNoise(img.rows, img.cols, img.type());
    cv::RNG rng;
    rng.fill(gaussNoise, cv::RNG::NORMAL, 0, 25);

    // cann 初始化及指定设备
    cv::cann::initAcl();
    cv::cann::setDevice(0);

    cv::Mat output;
    // 添加高斯噪声到输入图像
    cv::cann::add(img, gaussNoise, output);
    // 旋转图像 (0, 1, 2, 分别代表旋转 90°, 180°, 270°)
    cv::cann::rotate(output, output, 0);
    // 翻转图像 (0, 正数, 负数, 分别代表沿 x, y, x 和 y 轴进行翻转)
    cv::cann::flip(output, output, 0);
    // 写入输出图像
    cv::imwrite(outputPath, output);

    // cann 去初始化
    cv::cann::resetDevice();
    cv::cann::finalizeAcl();
    return 0;
}

这个需要NPU硬件支持,有条件的去试试。

1.3 OpenCV性能优化技巧

除了多线程和NPU加速,还有一些其他的技术和技巧可以用来优化OpenCV程序的性能,例如使用更高效的算法、减少不必要的内存拷贝、使用预分配内存等。

  1. 选择高效的算法:不同的算法在性能上可能有显著差异。例如,使用快速傅里叶变换(FFT)进行图像卷积通常比直接卷积更快。
  2. 减少内存拷贝:频繁的内存拷贝会显著降低程序的性能。尽量使用引用或指针来传递数据,避免不必要的拷贝。
  3. 预分配内存:在处理大量数据时,动态分配内存可能会导致性能瓶颈。预分配足够的内存可以避免频繁的内存分配和释放。

下面是一个减少内存拷贝的示例:

c++ 复制代码
#include <opencv2/opencv.hpp>

void processImage(cv::Mat& img) {
    cv::Mat gray;
    cv::cvtColor(img, gray, cv::COLOR_BGR2GRAY);

    cv::Mat blurred;
    cv::GaussianBlur(gray, blurred, cv::Size(5, 5), 0);

    cv::Mat edges;
    cv::Canny(blurred, edges, 50, 150);
    
    if (img.channels() == 3) {
        cv::cvtColor(edges, img, cv::COLOR_GRAY2BGR);
    } else {
        img = edges.clone();
    }
}

int main() {
    cv::Mat img = cv::imread("input.jpg");
    if (img.empty()) {
        std::cerr << "Could not open or find the image" << std::endl;
        return -1;
    }

    processImage(img);
    cv::imwrite("output.jpg", img);
    return 0;
}

瞬间执行完:

相关推荐
ILUUSION_S11 小时前
ReactAgent接入MCP服务工具
python·langchain
胖达不服输11 小时前
「日拱一码」076 深度学习——自然语言处理NLP
人工智能·python·深度学习·自然语言处理·nlp
LeonDL16811 小时前
基于YOLO11深度学习的植物叶片及缺陷检测系统【Python源码+Pyqt5界面+数据集+安装使用教程+训练代码】【附下载链接】
python·深度学习·yolo目标检测·yolov5数据集·yolov8数据集·yolo11数据集·植物叶片及缺陷检测系统
BillKu11 小时前
Spring Boot 后端接收多个文件的方法
spring boot·后端·python
hui函数12 小时前
订单后台管理系统-day07菜品模块
数据库·后端·python·flask
小李小李无与伦比12 小时前
MinerU环境部署——PDF转Markdown
开发语言·python·深度学习·conda
胡耀超12 小时前
AI:大语言模型微调的真相:打破迷思,理性选择
python·ai·大模型·llm·微调·提示词·大模型应用指南
大学生毕业题目12 小时前
毕业项目推荐:52-基于yolov8/yolov5/yolo11的红绿灯检测识别系统(Python+卷积神经网络)
人工智能·python·yolo·目标检测·cnn·pyqt·红绿灯检测
人生游戏牛马NPC1号12 小时前
学习 Android (十八) 学习 OpenCV (三)
android·opencv·学习