Replacing the color in the image file



  • hi,

    I want to replace the colour in the image file.

    I used the following code and its masking the color but not replacing. how to replace?

    @
    QRect rect(50, 50, width(), height());
    QPainter p(printer);
    QPixmap pix("AutoCurveFitting.png");
    QBitmap mask = pix.createMaskFromColor(QColor(0, 0, 0), Qt::MaskOutColor);
    p.setPen(QColor(255, 255, 255));
    p.drawPixmap(pix.rect(), mask, mask.rect());
    p.end();@



  • replace color, do you mean you want to change red to blue,blue to green or yellow red etc?

    If this is what you want, there are a very simple algorithm

    1 : change your color space from RGB to HSV(or HSL etc, the important part is separate the color into hue, saturation and intensity)

    2 : Find out the range of the specific color you want to change. ex : red is within 20~40(not exactly, just an example), green is within(41~60)

    3 : Add the value of hue 20 if the range of the pixels between 20~40, and decrease the value of hue 20 if the range of the pixels between 41~60, this should change the color from red to green, green to red.



  • Hi,

    Thank you very much.

    But how to change the color space from RGB to HSV?



  • yea i found how to change hsv to rgb and vice versa as below,
    but how to apply hsv change to qpixmap?

    @RgbColor Dialog::HsvToRgb(HsvColor hsv)
    {
    RgbColor rgb;
    unsigned char region, remainder, p, q, t;

    if (hsv.s == 0)
    {
        rgb.r = hsv.v;
        rgb.g = hsv.v;
        rgb.b = hsv.v;
        return rgb;
    }
    
    region = hsv.h / 43;
    remainder = (hsv.h - (region * 43)) * 6;
    
    p = (hsv.v * (255 - hsv.s)) >> 8;
    q = (hsv.v * (255 - ((hsv.s * remainder) >> 8))) >> 8;
    t = (hsv.v * (255 - ((hsv.s * (255 - remainder)) >> 8))) >> 8;
    
    switch (region)
    {
        case 0:
            rgb.r = hsv.v; rgb.g = t; rgb.b = p;
            break;
        case 1:
            rgb.r = q; rgb.g = hsv.v; rgb.b = p;
            break;
        case 2:
            rgb.r = p; rgb.g = hsv.v; rgb.b = t;
            break;
        case 3:
            rgb.r = p; rgb.g = q; rgb.b = hsv.v;
            break;
        case 4:
            rgb.r = t; rgb.g = p; rgb.b = hsv.v;
            break;
        default:
            rgb.r = hsv.v; rgb.g = p; rgb.b = q;
            break;
    }
    
    return rgb;
    

    }

    HsvColor Dialog::RgbToHsv(RgbColor rgb)
    {
    HsvColor hsv;
    unsigned char rgbMin, rgbMax;

    rgbMin = rgb.r < rgb.g ? (rgb.r < rgb.b ? rgb.r : rgb.b) : (rgb.g < rgb.b ? rgb.g : rgb.b);
    rgbMax = rgb.r > rgb.g ? (rgb.r > rgb.b ? rgb.r : rgb.b) : (rgb.g > rgb.b ? rgb.g : rgb.b);
    
    hsv.v = rgbMax;
    if (hsv.v == 0)
    {
        hsv.h = 0;
        hsv.s = 0;
        return hsv;
    }
    
    hsv.s = 255 * long(rgbMax - rgbMin) / hsv.v;
    if (hsv.s == 0)
    {
        hsv.h = 0;
        return hsv;
    }
    
    if (rgbMax == rgb.r)
        hsv.h = 0 + 43 * (rgb.g - rgb.b) / (rgbMax - rgbMin);
    else if (rgbMax == rgb.g)
        hsv.h = 85 + 43 * (rgb.b - rgb.r) / (rgbMax - rgbMin);
    else
        hsv.h = 171 + 43 * (rgb.r - rgb.g) / (rgbMax - rgbMin);
    
    return hsv;
    

    }@



  • bq. but how to apply hsv change to qpixmap?

    Not sure what are you talking about?
    You could apply the color space transformation algorithm
    on the QImage or QPixmap directly



  • You could give openCV a try, a famous image processing library, although the api of openCV are not very well designed(I think this is because they want to support legacy api), but the features and algorithms of this library are rich and very easy to use.

    Do remember to use the api of openCV2(api of c++), openCV will drop C API support soon. C++ is much better.

    "openCV 3.0 overview":bit.ly/icvs_opencv_3

    example from the pdf

    C vs C++ API: Focus Detector

    c api
    @
    double calcGradients(const IplImage *src,
    int aperture_size = 7)
    {
    CvSize sz = cvGetSize(src);

    IplImage* img16_x = cvCreateImage(sz, IPL_DEPTH_16S, 1);
    IplImage* img16_y = cvCreateImage(sz, IPL_DEPTH_16S, 1);
    cvSobel(src, img16_x, 1, 0, aperture_size);
    cvSobel(src, img16_y, 0, 1, aperture_size);
    IplImage* imgF_x = cvCreateImage(sz, IPL_DEPTH_32F, 1);
    IplImage* imgF_y = cvCreateImage(sz, IPL_DEPTH_32F, 1);
    cvScale(img16_x, imgF_x);
    cvScale(img16_y, imgF_y);
    IplImage* magnitude = cvCreateImage(sz, IPL_DEPTH_32F, 1);
    cvCartToPolar(imgF_x, imgF_y, magnitude);
    double res = cvSum(magnitude).val[0];

    cvReleaseImage(&magnitude );
    cvReleaseImage(&imgF_x);
    cvReleaseImage(&imgF_y);
    cvReleaseImage(&img16_x);
    cvReleaseImage(&img16_y);

    return res;
    }
    @

    c++
    @
    double contrast_measure(Mat& img)
    {
    Mat dx, dy;
    Sobel(img, dx, 1, 0, 3, CV_32F);
    Sobel(img, dy, 0, 1, 3, CV_32F);
    magnitude(dx, dy, dx);

    return sum(dx)[0];
    }
    @

    performance?from the benchmark, you could say there are almost no difference, due to better optimization(template tricks, inline etc), the codes of c++ even could be a little bit faster than c.
    openCV is one of the good library to show us that the performance of c++ and c are equal, but with better api and higher level of abstraction if you know how to leverage the power of c++.



  • Thank you very much.

    I will give a try .


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.