PeakGen
PeakGen

Reputation: 23035

Negative image is completly black

Here is my code, which uses OpenCV 2.4.5

Histogram1D.h

#ifndef HISTOGRAM1D_H
#define HISTOGRAM1D_H

#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

using namespace std;
using namespace cv;

class Histogram1D
{
public:
    Histogram1D();

    //Histogram generators
    MatND getHistogram(Mat );
    Mat getHistogramImage(Mat );

    //Generate Negative Image
    Mat applyLookup(Mat ,Mat );

    //Generate improved image with equalized histogram
    Mat equalize(Mat image);

private:
    int histSize[1];//Number of bins
    float hRanges[2];//Max and Min pixel values
    const float *ranges[1];
    int channels[1];//Only one channel will be used
};

#endif // HISTOGRAM1D_H

Histogram1D.cpp

#include "Histogram1D.h"


Histogram1D::Histogram1D()
{
    histSize[0] = 256;

    hRanges[0] = 0.0;
    hRanges[1] = 255.0;

    ranges[0] = hRanges;

    channels[0] = 0;
}

MatND Histogram1D::getHistogram(Mat image)
{
    MatND hist;

    cv::calcHist(&image,1,channels,Mat(),hist,1,histSize,ranges);

    return hist;
}

Mat Histogram1D::getHistogramImage(Mat image)
{
    MatND histo = getHistogram(image);

    //Get minimum and maximum value bins
    double minVal = 0;
    double maxVal = 0;

    minMaxLoc(histo,&minVal,&maxVal,0,0);

    //Image on which to display histogram
    Mat histImage(histSize[0],histSize[0],CV_8U,Scalar(255));

    //Set highest point at 90% of nbins
    int hpt = static_cast<int>(0.9,histSize[0]);

    //Draw a vertical line for each bin
    for(int i=0;i<histSize[0];i++)
    {
        float binVal = histo.at<float>(i);

        int intensity = static_cast<int>(binVal*hpt/maxVal);

        line(histImage,Point(i,histSize[0]),Point(i,histSize[0]-intensity),Scalar::all(0));
    }

    return histImage;


}

Mat Histogram1D::applyLookup(Mat image,Mat lookup)
{
    Mat result;

    cv::LUT(image,lookup,result);
    return result;
}



Mat Histogram1D::equalize(Mat image)
{
    Mat result;

    cv::equalizeHist(image,result);
    return result;
}

HistogramMain.cpp

#include "Histogram1D.h"

int main()
{
    Histogram1D h;

    Mat image = imread("C:/Users/Public/Pictures/Sample Pictures/Penguins.jpg",CV_LOAD_IMAGE_GRAYSCALE);
    cout << "Number of Channels: " << image.channels() << endl;

    namedWindow("Image");
    imshow("Image",image);



    Mat histogramImage = h.getHistogramImage(image);
    namedWindow("Histogram");
    imshow("Histogram",histogramImage);

    Mat thresholded;
    threshold(image,thresholded,60,255,THRESH_BINARY);
    namedWindow("Binary Image");
    imshow("Binary Image",thresholded);


    Mat negativeImage;
    int dim(256);
    negativeImage = h.applyLookup(image,Mat(1,&dim,CV_8U));
    namedWindow("Negative Image");
    imshow("Negative Image",negativeImage);



    Mat equalizedImage;
    equalizedImage = h.equalize(image);
    namedWindow("Equalized Image");
    imshow("Equalized Image",equalizedImage);


    waitKey(0);
    return 0;
}

When you run this code, the negative image is 100% black! The most amazing this is, if you remove all other code from HistogramMain.cpp but keep the code below which is related to negative image, you will get the correct negative image! Why is this?

I am using QT latest version which use the VS 2010 Compiler.

Mat negativeImage;
    int dim(256);
    negativeImage = h.applyLookup(image,Mat(1,&dim,CV_8U));
    namedWindow("Negative Image");
    imshow("Negative Image",negativeImage);

Upvotes: 1

Views: 1311

Answers (2)

Alexandre Mazel
Alexandre Mazel

Reputation: 2558

By the way, with opencv2 image are now numpy array, so to negative a grey 8-bits image in python, it's simply:

img = 255 - img

Upvotes: 1

Aurelius
Aurelius

Reputation: 11359

Your primary difficulty is that the expression Mat(1,&dim,CV_8U) allocates memory for a cv::Mat, but does not initialize any values. It is possible that your environment may fill uninitialized memory with zeros, which would explain the black image after calling applyLookup(). In any case, you should initialize the values in your lookup table in order to achieve correct results. For inverting the image, it is easy:

int dim(256);
cv::Mat tab(1,&dim,CV_8U);
uchar* ptr = tab.ptr();

for (size_t i = 0; i < tab.total(); ++i)
{
    ptr[i] = 255 - i;
}

There are a few other issues with your code:

The line

int hpt = static_cast<int>(0.9,histSize[0]);

should be

int hpt = static_cast<int>(0.9*histSize[0]);

to do what your comment indicates. Pay attention to your compiler warnings!

You also have problems with your histogram ranges.

Upvotes: 1

Related Questions