Ask Your Question
0

I need an equalization function with mask like this: equalizeHist(src, dst, mask)

asked 2014-02-26 02:36:38 -0600

Jupiter gravatar image

In order to be able to process complicated regions, I need a equalizeHist function with 3 arguments. But unfortunally, in OpenCV it is not implemented. Is there any workaround? Thank you.

edit retag flag offensive close merge delete

Comments

Yes there is, download the source code, find yourself the implementation of equalizeHist, adapt it to your needs and rebuilt openCV on your system. Or you could do the following using the openCV functionality:

- define a second Mat image which is a subregion of a larger Mat
- apply the equalizeHist on that subregion
- copy back the information to the original image

However, this will only work with rectangular regions, but it could suit your needs.

StevenPuttemans gravatar imageStevenPuttemans ( 2014-02-26 03:31:32 -0600 )edit

And how about using MaskROI with Mat? Can I form a non-rectangular Region Of Interest?

Jupiter gravatar imageJupiter ( 2014-02-26 03:44:38 -0600 )edit

Not for this equalize hist, because the function requires a data matrix and just uses pixel intensities. It is not possible to ignore values there.

StevenPuttemans gravatar imageStevenPuttemans ( 2014-02-26 04:42:37 -0600 )edit

I found implementation of equalizeHist(src, dst, mask) on the net: https://github.com/hengli/camodocal/blob/cd2044ace16c0847c132582034cefacd76122f2b/src/gpl/OpenCVUtils.h

Resolved ))

Jupiter gravatar imageJupiter ( 2014-02-27 01:56:37 -0600 )edit

It might be a good idea to submit this solution as a pull request to openCV. I do think many people will enjoy this new functionality!

StevenPuttemans gravatar imageStevenPuttemans ( 2014-02-27 02:53:43 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
0

answered 2014-02-27 02:49:37 -0600

This solution was pasted from the original authors solution. However, to guarantee this will work in the feature, this should be kept as code here:

#ifndef OPENCVUTILS_H
#define OPENCVUTILS_H

#include <iostream>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/imgproc/imgproc_c.h>
#include <opencv2/core/internal.hpp>

void cvEqualizeHist( const CvArr* srcarr, CvArr* dstarr, CvMat* mask )
{
    using namespace cv;

    CvMat sstub, *src = cvGetMat(srcarr, &sstub);
    CvMat dstub, *dst = cvGetMat(dstarr, &dstub);

    CV_Assert( CV_ARE_SIZES_EQ(src, dst) && CV_ARE_TYPES_EQ(src, dst) &&
               CV_MAT_TYPE(src->type) == CV_8UC1 );

    CV_Assert( CV_ARE_SIZES_EQ(src, mask) && CV_MAT_TYPE(mask->type) == CV_8UC1);

    CvSize size = cvGetMatSize(src);
    if( CV_IS_MAT_CONT(src->type & dst->type) )
    {
        size.width *= size.height;
        size.height = 1;
    }
    int x, y;
    const int hist_sz = 256;
    int hist[hist_sz];
    memset(hist, 0, sizeof(hist));

    for( y = 0; y < size.height; y++ )
    {
        const uchar* sptr = src->data.ptr + src->step*y;
        const uchar* mptr = mask->data.ptr + mask->step*y;
        for( x = 0; x < size.width; x++ )
            if (mptr[x]) hist[sptr[x]]++;
    }

    float scale = 255.f/(cvCountNonZero(mask));
    int sum = 0;
    uchar lut[hist_sz+1];

    for( int i = 0; i < hist_sz; i++ )
    {
        sum += hist[i];
        int val = cvRound(sum*scale);
        lut[i] = CV_CAST_8U(val);
    }

    lut[0] = 0;
    cvSetZero(dst);
    for( y = 0; y < size.height; y++ )
    {
        const uchar* sptr = src->data.ptr + src->step*y;
        const uchar* mptr = mask->data.ptr + mask->step*y;
        uchar* dptr = dst->data.ptr + dst->step*y;
        for( x = 0; x < size.width; x++ )
            if (mptr[x]) dptr[x] = lut[sptr[x]];
    }
}

void equalizeHist(cv::InputArray _src, cv::OutputArray _dst, cv::InputArray _mask = cv::noArray())
{
    using namespace cv;

    Mat src = _src.getMat().clone();
    _dst.create( src.size(), src.type() );
    Mat dst = _dst.getMat();
    Mat mask;
    if (_mask.empty()) mask = Mat::ones(src.size(), CV_8UC1);
    else mask = _mask.getMat();
    CvMat _csrc = src, _cdst = dst, _cmask = mask;
    cvEqualizeHist( &_csrc, &_cdst, &_cmask);
}

#endif
edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2014-02-26 02:36:38 -0600

Seen: 2,355 times

Last updated: Feb 27 '14