2

I have two images. One has more green color and another one has better quality (it has right color). How can I improve the first one to have the similar color as the second one.I used the contrast enhancement as

//Contrast enhancement
    for (int y = 0; y < rotated.rows; y++)
    {
        for (int x = 0; x < rotated.cols; x++)
        {
            for (int c = 0; c < 3; c++)
            {
                //"* Enter the alpha value [1.0-3.0]: "
                //"* Enter the beta value [0-100]: ";
                rotated.at<Vec3b>(y, x)[c] =
                    saturate_cast<uchar>(2.5*(rotated.at<Vec3b>(y, x)[c]) + 30);
            }
        }
    }

It brightens the image. But I like to have similar color as the second one. What are the RGB values to change to have the second image's color. enter image description here enter image description here

batuman
  • 7,066
  • 26
  • 107
  • 229

1 Answers1

1

For contrast enhancement you can use the equivalent of Matlab imadjust. You can find an OpenCV implementation here.

Applying imadjust with default parameters on each separate channel you get:

enter image description here

Here the full code:

#include <opencv2\opencv.hpp>
#include <vector>
#include <algorithm>

using namespace std;
using namespace cv;

void imadjust(const Mat1b& src, Mat1b& dst, int tol = 1, Vec2i in = Vec2i(0, 255), Vec2i out = Vec2i(0, 255))
{
    // src : input CV_8UC1 image
    // dst : output CV_8UC1 imge
    // tol : tolerance, from 0 to 100.
    // in  : src image bounds
    // out : dst image buonds

    dst = src.clone();

    tol = max(0, min(100, tol));

    if (tol > 0)
    {
        // Compute in and out limits

        // Histogram
        vector<int> hist(256, 0);
        for (int r = 0; r < src.rows; ++r) {
            for (int c = 0; c < src.cols; ++c) {
                hist[src(r, c)]++;
            }
        }

        // Cumulative histogram
        vector<int> cum = hist;
        for (int i = 1; i < hist.size(); ++i) {
            cum[i] = cum[i - 1] + hist[i];
        }

        // Compute bounds
        int total = src.rows * src.cols;
        int low_bound = total * tol / 100;
        int upp_bound = total * (100 - tol) / 100;
        in[0] = distance(cum.begin(), lower_bound(cum.begin(), cum.end(), low_bound));
        in[1] = distance(cum.begin(), lower_bound(cum.begin(), cum.end(), upp_bound));

    }

    // Stretching
    float scale = float(out[1] - out[0]) / float(in[1] - in[0]);
    for (int r = 0; r < dst.rows; ++r)
    {
        for (int c = 0; c < dst.cols; ++c)
        {
            int vs = max(src(r, c) - in[0], 0);
            int vd = min(int(vs * scale + 0.5f) + out[0], out[1]);
            dst(r, c) = saturate_cast<uchar>(vd);
        }
    }
}

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

    vector<Mat1b> planes;
    split(img, planes);

    for (int i = 0; i < 3; ++i)
    {
        imadjust(planes[i], planes[i]);
    }

    Mat3b result;
    merge(planes, result);

    return 0;
}
Community
  • 1
  • 1
Miki
  • 40,887
  • 13
  • 123
  • 202
  • It might be useful to provide details as to how you compile your program and what platform you are on so others can follow along... just a thought. – Mark Setchell Sep 29 '15 at 20:49
  • @MarkSetchell it's a C++ program linked OpenCV (as in the question). Whatever OS, IDE or C++ compiler will work. There is something I'm missing? – Miki Sep 29 '15 at 20:53
  • All I am suggesting is that your answer might be more useful and maybe garner more votes if it said *"I'm on Ubuntu and I compile with `gcc -I something -Dsomething -O2 -Lsomewhere -lopencv -lfunkylibXYZ`"* – Mark Setchell Sep 29 '15 at 21:01
  • ...but since I used Visual Studio on Win8 and linked OpenCV through VS properties, I don't think my command line will be useful... – Miki Sep 29 '15 at 21:09