c++ - 底片全黑

标签 c++ visual-studio-2010 image qt opencv

这是我的代码,它使用 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

直方图1D.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);

最佳答案

您的主要困难是表达式 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 .

关于c++ - 底片全黑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16304144/

相关文章:

c++ - GCC 与 Cygwin/Win7 : missing syscall. h

c# - 在 datagridview 和表单之间传递数据的更有效方式

C# - 应用程序.EnableVisualStyles()

c# - 添加页码参数时,Report Services 在本地报告的 visual studio 调试器中崩溃

java - 更喜欢非成员非友元函数......在 Java 中?

C++ lambda 代表

c++ - WxWidgets - 无法加载图像

ImageMagick 和 Sprite 表

linux - 在 Linux 上将带有阿拉伯文本的 PDF 转换为图像

image - FB 调试器说我的 og :image should be larger, 即使它很大