【问题标题】:Python like Slicing operation in c++C++ 中类似 Python 的切片操作
【发布时间】:2020-07-27 19:53:43
【问题描述】:

我有以下代码,其中 'Snap.JPG' 是 RGB 格式类型。

import cv2

img = cv2.imread("./Snap.JPG")

img[:,:,:2] = 255

cv2.imshow("Img", img)
cv2.waitKey(0)
cv2.destroyAllWindows()

我想将此代码转换为 c++。实现img[:,:,:2] = 255部分代码的最快方法是什么?通道拆分和合并是我知道的选项之一,但是有没有更聪明的方法可以在 c++ 中进行切片?

编辑: 抱歉,我应该在输出中提到我想要的。我需要一个淡入淡出的效果,因为我想在它上面叠加一张图。

【问题讨论】:

  • 您能举例说明img[:,:,:2] 的作用吗?
  • 我认为它的计算结果是一个左值表达式。
  • 由于涉及副本,拆分和合并肯定不是最佳的。编译器应该能够优化所有元素的简单循环,您只覆盖Vec3b 的前两个部分。然后可能将其转换为 cv::ParallelLoopBody 的派生类,以便您可以使用 cv::parallel_for_... 运行它...或者这些天 lambda 也可以。
  • @cigien,我猜它会将所有ijk = 0, 1 设置为img[i, j, k]
  • @cigien 它为仅包含前两个通道的原始数组创建了一个视图。然后将 255 分配给第一个和第二个通道中的所有值。鉴于图像是 BGR(它是 OpenCV),这意味着图像中所有像素的所有蓝色和绿色强度都设置为 255。

标签: python c++ opencv


【解决方案1】:

这是一个如何改变像素的例子:

#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>

int main(int argc, char** argv) {
    cv::Mat src_image = cv::imread("image.jpg", CV_LOAD_IMAGE_COLOR);

    if(!src_image.data) {
        std::cout << "Error: the image wasn't correctly loaded." << std::endl;
        return -1;
    }

    cv::Mat image = src_image.clone();

    // We iterate over all pixels of the image
    for(int r = 0; r < image.rows; r++) {
        // We obtain a pointer to the beginning of row r
        cv::Vec3b* ptr = image.ptr<cv::Vec3b>(r);

        for(int c = 0; c < image.cols; c++) {
            ptr[c] = cv::Vec3b(255, 255, ptr[c][2]);
        }
    }

    cv::imshow("Inverted Image", image);
    cv::waitKey();

    return 0;
}

【讨论】:

    【解决方案2】:

    感谢@Manuel 的回复,效果很好。但我可以用更快的速度达到同样的效果。我已经添加了我的代码 sn-ps inline 你的代码。

    #include <opencv2/core.hpp>
    #include <opencv2/imgproc.hpp>
    #include <opencv2/highgui.hpp>
    #include <iostream>
    #include <iomanip>
    
    
    int main(int argc, char** argv) {
        clock_t start, end;
    
        cv::Mat src_image = cv::imread("Snap.JPG", CV_LOAD_IMAGE_COLOR);
    
        if(!src_image.data) {
            std::cout << "Error: the image wasn't correctly loaded." << std::endl;
            return -1;
        }
    
        /* 1st method */
        cv::Mat image = src_image.clone();
    
        start = clock();
        // We iterate over all pixels of the image
        for(int r = 0; r < image.rows; r++) {
            // We obtain a pointer to the beginning of row r
            cv::Vec3b* ptr = image.ptr<cv::Vec3b>(r);
    
            for(int c = 0; c < image.cols; c++) {
                ptr[c] = cv::Vec3b(255, 255, ptr[c][2]);
            }
        }
        end = clock();
    
        double time_taken = double(end - start) / double(CLOCKS_PER_SEC);
        std::cout << "Time taken by 1st method : " << std::fixed << time_taken << std::setprecision(5);
        std::cout << " sec " << std::endl;
    
        /* 2nd Method */
        start = clock();
        src_image = src_image | cv::Scalar(255, 255, 0);
        end = clock();
    
        time_taken = double(end - start) / double(CLOCKS_PER_SEC);
        std::cout << "Time taken by 2nd method : " << std::fixed << time_taken << std::setprecision(5);
        std::cout << " sec " << std::endl;
    
        bool isEqual = (sum(src_image != image) == cv::Scalar(0,0,0,0));
        if (isEqual)
        {
            std::cout << "\nIdentical Mats !" << std::endl;
        }
    
        cv::imshow("Inverted Image", image);
        cv::waitKey();
    
        return 0;
    }
    

    输出如下:

    Time taken by 1st method : 0.001765 sec
    Time taken by 2nd method : 0.00011 sec
    
    Identical Mats !
    

    【讨论】:

      猜你喜欢
      • 2011-01-31
      • 1970-01-01
      • 2010-11-13
      • 2017-02-09
      • 2019-12-16
      • 2019-10-27
      • 2018-11-06
      • 2020-03-14
      • 2013-08-03
      相关资源
      最近更新 更多