Reputation: 3063
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
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
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