3

I need a suggestion how to convert the image in rectangle into a grayscale image.

I want to convert the rectangle around the tube to grayscale:

for (int i = 612; i >= 0; i = i-204)
{
    cout << "i" << i << endl;

    rectangle( OI, Rect(i, 0, 161, 643),  1, 2, 8, 0 );
}   

imshow("Display window",OI);

I am using rectangle function to draw rectangle. Are there any suggestions for how can I convert the image in the rectangle into grayscale?

Miki
  • 40,887
  • 13
  • 123
  • 202

2 Answers2

2

You can:

  1. Crop the 3 channel image with a given rectangle
  2. Convert the cropped image to grayscale. The result will be a single channel image
  3. Convert the grayscale image to 3 channels, or you can't copy it into the original image
  4. Copy the 3 channel grayscale image into the original image.

Result (example with 2 roi):

enter image description here

Code:

#include <opencv2\opencv.hpp>
using namespace cv;

int main()
{
    // Your image
    Mat3b img = imread("path_to_image");

    // Your rects
    vector<Rect> rois{ Rect(50, 50, 200, 300), Rect(400, 100, 200, 380) };

    for (int i = 0; i < rois.size(); ++i)
    {
        // Convert each roi to grayscale
        Mat crop = img(rois[i]).clone();      // Crop is color CV_8UC3
        cvtColor(crop, crop, COLOR_BGR2GRAY); // Now crop is grayscale CV_8UC1
        cvtColor(crop, crop, COLOR_GRAY2BGR); // Now crop is grayscale, CV_8UC3
        crop.copyTo(img(rois[i]));            // Copy grayscale CV_8UC3 into color image
    }

    // Show results
    imshow("Result", img);
    waitKey();

    return 0;
}
Miki
  • 40,887
  • 13
  • 123
  • 202
  • Thank you very much for your suggestion. however I am not able to run your code. I am getting error like, microsoft visual studio 10.0\vc\include\vector(550): error C2664: 'void std::vector<_Ty>::_Construct<_Iter>(_Iter,_Iter,std::_Int_iterator_tag)' : cannot convert parameter 3 from 'int' to 'std::_Int_iterator_tag' 1> with 1> [ 1> _Ty=cv::Rect, 1> _Iter=cv::Rect_ 1> ] 1> No constructor could take the source type, or constructor overload resolution was ambiguous 1> 1>Build FAILED. how can I solve this problem. thank you again. – Ankit Ramani Nov 30 '15 at 15:04
  • 1
    @AnkitRamani It seems that you have not C++11 enabled. Try changing the vector line to: `vector rois; rois.push_back(Rect(...));` – Miki Nov 30 '15 at 15:06
  • Thank you very much for your time and suggestions. – Ankit Ramani Nov 30 '15 at 15:39
0

If the color space is RGB you need to average Red, Green and Blue and write the average to all the three samples. you will need a function per surface type.

Example assuming sample order RGBRGBRGB...

unsigned char* pLine = image[i]; // pointer to start of line 'i'
for (int j=0; i < width; ++j) { // width is pixels per line
   int gray = ((pLine[j*3] + pLine[j*3 + 1] + pLine[j*2]) + 1) / 3;
   pLine[j*3] = pLine[j*3 + 1] = pLine[j*2]= (unsigned char)gray;
}

if the color space is YCbCr/YUV you need to write 128 to all Cb/Cr or UV samples, keeping 'Y' as is. 'Y' is the gray level.

If you want to calculate the gray level better, you can use a similar formula to the one used in RGB->YUV conversion. 70% green, 20% red and 10% blue.

egur
  • 7,830
  • 2
  • 27
  • 47