2013-04-30 97 views
1

请看下面的代码。它是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; 
} 

当你运行这个代码时,负面图像是100%黑色!最令人惊讶的是,如果您从HistogramMain.cpp中删除所有其他代码,但保留下面与负像相关的代码,您将获得正确的负像!为什么是这样?如果有帮助,我使用的是使用VS 2010编译器的QT最新版本。请帮忙!

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

回答

1

您的主要困难是,表达Mat(1,&dim,CV_8U)用于cv::Mat分配内存,但不初始化任何值。您的环境可能会用零填充未初始化的内存,这将在调用applyLookup()后解释黑色图像。无论如何,您应该初始化查找表中的值以获得正确的结果。对于反转的形象,很容易:

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

还有一些其他问题与您的代码:

线

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

应该

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

做你的评论表明什么。注意你的编译器警告!

您的直方图ranges也存在问题。

+0

太好了!非常感谢! – 2013-05-04 07:03:28

1

顺便说一句,与opencv2像现在numpy的阵列,所以要负一个灰色的8位图像的蟒蛇,它只是:

img = 255 - img 
+0

这也适用于C++。 – 2015-04-02 06:40:20