Milind Deore
Milind Deore

Reputation: 3063

Python like Slicing operation in c++

I have following code, where 'Snap.JPG' is a RGB format type.

import cv2

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

img[:,:,:2] = 255

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

I want to convert this code into c++. What is the fastest way to implement img[:,:,:2] = 255 part of the code? Channel splitting and merging is one of the options i know, but is there any smarter way to do slicing in c++?

Edit: Apologies, i should have mentioned what i want in the output. I need a fading effect, because i wanted to overlay a drawing on top of it.

Upvotes: 0

Views: 328

Answers (2)

Milind Deore
Milind Deore

Reputation: 3063

Thanks for @Manuel's reply, it works quite well. but i could achieve the same result with faster speeds. I have added my code snippets inline your code.

#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;
}

output is following:

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

Identical Mats !

Upvotes: 2

Manuel
Manuel

Reputation: 2554

This is an example of how to change pixels:

#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;
}

Upvotes: 2

Related Questions