Question: 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:

![](https://i.stack.imgur.com/XjYO3.png)

```
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?

Answer: 
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](https://i.stack.imgur.com/1VX20.jpg)](https://i.stack.imgur.com/1VX20.jpg)

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

```
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.