侧边栏壁纸
  • 累计撰写 154 篇文章
  • 累计收到 0 条评论

51c视觉~CV~合集11

2025-4-27 / 0 评论 / 16 阅读

一、C++ 和 Python 融合以实现高效计算机视觉应用

计算机视觉应用既需要卓越的图像处理性能,也需要现代机器学习框架的灵活性。在本指南中,我们实现了一个模块化的计算机视觉流程,涵盖以下内容:

  • 图像处理:使用 OpenCV 在 C++ 中应用快速高斯模糊,并使用 pybind11 呈现给 Python。
  • 建模和分类:一个 Python 模块,用于提取简单特征、训练机器学习分类器(使用 scikit-learn)并对新图像进行分类。

    这种架构允许您利用 Python 强大的生态系统进行模型构建和实验,并在需要时利用 C++ 的速度。

先决条件和环境设置

    开始之前,请确保已安装以下软件:

  • Python 3.10.11
  • C++ 编译器:兼容 C++11(或更新版本)
  • OpenCV:用于 C++ 和 Python 中的图像处理
  • pybind11:用于创建 Python 到 C++ 代码的绑定
  • NumPy:用于 Python 中的数值运算
  • scikit-learn:用于构建和评估分类器

    您可以使用 pip3 安装必要的 Python 包:

undefined | 复制pip3 install numpy opencv-python-headless scikit-learn pybind11

    按照你的 C++ 编程平台的指南安装 OpenCV 和 pybind11。使用 CMake(或直接从编译器)运行的标准编译命令可能如下所示:

r | 复制1
2
3
c++ -O3 -Wall -shared -std=c++11 -fPIC \
    `python3 -m pybind11 --includes` fast_blur.cpp -o fast_blur`python3-config --extension-suffix` \
    $(pkg-config --cflags --libs opencv4)

第 1 部分:使用 C++ 和 Python 集成进行图像处理

    在性能至关重要的图像处理中,C++ 可以显著加速流程。我们将使用 OpenCV 的高斯模糊构建一个基本的 C++ 模块。此代码将图片作为 NumPy 数组,应用高斯模糊,并输出结果图像。

    C++代码:fast_blur.cpp

c++ | 复制1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <pybind11/pybind11.h>
#include <pybind11/numpy.h>
#include <opencv2/opencv.hpp>
#include <stdexcept>
#include <cstring>

namespace py = pybind11;
// Applies a Gaussian blur to a 3-channel image.
// The input is expected to be a NumPy array of shape (height, width, channels).
py::array_t<unsigned char> gaussian_blur(py::array_t<unsigned char> input, int kernel_size, double sigma) {
    // Request a buffer descriptor from Python
    auto buf = input.request();
    if (buf.ndim != 3)
        throw std::runtime_error("Input image must be 3-dimensional");
    int height = buf.shape[0];
    int width  = buf.shape[1];
    int channels = buf.shape[2];
    // Wrap the raw buffer as a cv::Mat.
    cv::Mat img(height, width, CV_8UC3, (unsigned char*)buf.ptr);

    // Apply Gaussian Blur using OpenCV.
    cv::Mat blurred;
    cv::GaussianBlur(img, blurred, cv::Size(kernel_size, kernel_size), sigma);
    // Construct a NumPy array to hold the result.
    // Note: pybind11 will manage the memory for you.
    return py::array_t<unsigned char>(
        // shape
        {height, width, channels},  
        {width * channels * sizeof(unsigned char), channels * sizeof(unsigned char), sizeof(unsigned char)}, // strides
        // pointer to data
        blurred.data  
    );
}
PYBIND11_MODULE(fast_blur, m) {
    m.doc() = "Module for fast image blur using C++ and OpenCV";
    m.def("gaussian_blur", &gaussian_blur, "Apply Gaussian Blur to an image",
          py::arg("input"), py::arg("kernel_size"), py::arg("sigma"));
}

    解释

  • 缓冲区协议:我们使用 pybind11 的缓冲区接口直接处理 NumPy 数组。
  • OpenCV 集成:处理后,图像作为包裹在 cv::Mat 中的新 NumPy 数组返回。
  • 编译:要编译此模块,请确保您的系统已正确设置 OpenCV 和 pybind11。

    编译完成后,您可以在 Python 中将此模块导入为 fast_blur。

第 2 部分:用于图像处理和分类的模块化 Python 代码

    C++ 模块准备就绪后,您可以将其添加到 Python 模块中,以进行额外的建模和计算。我们将流程分为两部分:一部分用于建模或分类,另一部分用于图像处理。

    Python模块:image_processing.py

    该模块利用我们的 C++ 模块实现快速高斯模糊,管理图片 I/O 和处理。

python | 复制1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import cv2
import numpy as np
import fast_blur

def load_image(path):
    image = cv2.imread(path)
    if image is None:
        raise IOError("Unable to load image at " + path)
    return image
def process_image(image, kernel_size=5, sigma=1.0):
    # Convert to appropriate type if needed (OpenCV uses uint8 images)
    blurred = fast_blur.gaussian_blur(image, kernel_size, sigma)
    return blurred
if __name__ == "__main__":
    # Example usage: process an image and save the result
    image = load_image("sample.jpg")  # Make sure 'sample.jpg' exists
    blurred_image = process_image(image)
    cv2.imwrite("blurred_sample.jpg", blurred_image)
    print("Blurred image saved as 'blurred_sample.jpg'")

    Python模块:classification.py

    此模块演示了一个简单的分类流程。在这里,我们:

  • 从图像中提取特征(使用颜色直方图)
  • 从文件夹结构准备数据集(每个子文件夹被视为一个类)
  • 使用 scikit-learn 训练 SVM 分类器
  • 使用分类器预测新图像的类别
python | 复制1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import cv2
import numpy as np
import os
from sklearn import svm
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

def extract_feature(image):
    # Calculate a 3D color histogram
    hist = cv2.calcHist([image], [0, 1, 2], None, [8, 8, 8], [0, 256, 0, 256, 0, 256])
    cv2.normalize(hist, hist)
    return hist.flatten()

def prepare_dataset(folder_path):
    features = []
    labels = []
    for label in os.listdir(folder_path):
        class_folder = os.path.join(folder_path, label)
        if os.path.isdir(class_folder):
            for filename in os.listdir(class_folder):
                img_path = os.path.join(class_folder, filename)
                image = cv2.imread(img_path)
                if image is not None:
                    feat = extract_feature(image)
                    features.append(feat)
                    labels.append(label)
    return np.array(features), np.array(labels)

def train_classifier(features, labels):
    clf = svm.SVC(kernel='linear')
    clf.fit(features, labels)
    return clf

def classify_image(image, classifier):
    feature = extract_feature(image)
    prediction = classifier.predict([feature])
    return prediction[0]

if __name__ == "__main__":
    # Make sure to organize your dataset accordingly.
    dataset_path = "dataset"  
    X, y = prepare_dataset(dataset_path)

    # Split the dataset into training and test sets
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

    # Train the classifier and evaluate its performance
    classifier = train_classifier(X_train, y_train)
    predictions = classifier.predict(X_test)
    print("Classification Accuracy:", accuracy_score(y_test, predictions))

    解释

  • 特征提取:为简单起见,我们使用像素强度的 3D 直方图作为特征向量。
  • 数据集准备:该函数从由类标签构成的目录中读取图像。
  • 分类器:我们使用来自 scikit-learn 的线性支持向量机 (SVM)。

第 3 部分:构建模块化项目

    模块化项目结构使您的代码更易于管理、测试和扩展。组织文件的一种方法如下:

php | 复制1
2
3
4
5
6
7
computer_vision_project/ 
── CMakeLists.txt             # 如果使用 CMake 作为 C++ 模块
── fast_blur.cpp              # 用于快速图像处理的 C++ 代码
── image_processing.py        # 用于图像处理的 Python 模块
── classified.py          # 用于特征提取和分类的 Python 模块
── main.py                    # 将模块绑定在一起的驱动程序脚本
└── dataset/                   # 包含每个类的子目录的示例数据集

    main.py 示例

    该文件将所有内容联系在一起:它使用图像处理模块预处理图片,并使用分类模块预测其类别。

python | 复制1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
from image_processing import load_image, process_image
from classification import classify_image, prepare_dataset, train_classifier
import cv2

def main():
    # Step 1: Preprocess an image using the C++ Gaussian blur module.
    image_path = "sample.jpg" 
    image = load_image(image_path)
    processed_image = process_image(image, kernel_size=7, sigma=2.0)
    cv2.imwrite("processed_sample.jpg", processed_image)
    print("Processed image saved as 'processed_sample.jpg'.")
    # Step 2: Train a classifier using a pre-organized dataset.
    dataset_path = "dataset"  
    features, labels = prepare_dataset(dataset_path)
    classifier = train_classifier(features, labels)

    # Step 3: Classify the processed image.
    predicted_class = classify_image(processed_image, classifier)
    print("Predicted class for the processed image:", predicted_class)

if __name__ == "__main__":
    main()

结 论

    本文中我们演示了如何构建一个实用的计算机视觉管道,它结合了以下内容:

  • C++ 和 Python 集成:利用 pybind11 集成 C++ 模块,以便使用 OpenCV 进行快速图像处理。
  • 模块化 Python 代码:为图像处理和机器学习分类实现单独的模块,这使得项目更易于维护和扩展。

    这种模块化方法不仅性能卓越,还能简化不同算法和模型的实验。您可以通过添加更高级的特征提取器、集成深度学习框架或优化 C++ 中其他性能关键部分来扩展此项目。











二、



三、