Reputation: 339
I used copyMakeBorder to create a 100x100x100x100 border around my image. I would like to use cvtColor to convert only the part of the image that is inside the border to gray, so the border remains bgr, I don't want to have to use copyTo to copy something inside the border on the image, I would like to process the image in place. I looked all over google and there was no specific code example to do this. May I ask someone provide code example.
Upvotes: 1
Views: 2657
Reputation: 4074
What Ed.S suggested is right - in opencv you cannot take some ROI from the bigger image and convert it in place from rgb to grayscale not converting whole image:
Mat src(1024, 768, CV_8UC3);
src.setTo(Scalar(255, 200, 100));
Mat roi = src(Rect(100, 100, 300, 300));
cvtColor(roi, roi, CV_RGB2GRAY); // nothing changed, still src is the same after cvtColor
What you can do is to perform conversion to grayscale by hand in the selected roi, what does not involve copying, rather that works in place:
Mat src(1024, 768, CV_8UC3);
src.setTo(cv::Scalar(255, 200, 100));
cv::imwrite("out.jpg", src);
Mat roi = src(cv::Rect(100, 100, 300, 300));
for(int i=0;i<roi.cols;i++)
for(int j=0;j<roi.rows;j++) {
cv::Vec3b p = roi.at<cv::Vec3b>(j,i);
unsigned char lumination = (unsigned char)( 0.2126*p[2] + 0.7152*p[1] + 0.0722*p[0]);
p[0] = p[1] = p [2] = lumination;
roi.at<cv::Vec3b>(j,i) = p;
}
EDIT: here's a lena example:
Mat src = imread("lena.jpg");
Mat roi = src(cv::Rect(src.cols/4, src.cols/4, src.cols/2, src.rows/2));
for(int i=0;i<roi.cols;i++)
for(int j=0;j<roi.rows;j++) {
cv::Vec3b p = roi.at<cv::Vec3b>(j,i);
unsigned char lumination = (unsigned char)( 0.2126*p[2] + 0.7152*p[1] + 0.0722*p[0]);
p[0] = p[1] = p [2] = lumination;
roi.at<cv::Vec3b>(j,i) = p;
}
cv::imwrite("out.jpg", src);
Result:
Upvotes: 3