首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我使用Open来创建RGB到HSI,然后做一个直方图。然后进行傅里叶变换,再返回HSI到RGB。

我使用Open来创建RGB到HSI,然后做一个直方图。然后进行傅里叶变换,再返回HSI到RGB。
EN

Stack Overflow用户
提问于 2015-04-25 15:47:12
回答 2查看 568关注 0票数 0

我无法调试这个程序。我将把RGB转换为HSI,然后在任何通道中放置一个直方图。在傅立叶之前和傅立叶之后。

代码语言:javascript
复制
#include "stdafx.h"
#include <opencv2/opencv.hpp>
#include <opencv\highgui.h>
#include <iostream>
// ass.cpp : Converts the given RGB image to HSI colour space then
//           performs Fourier filtering on a particular channel.
//

using namespace std;
using namespace cv;

// Declarations of 4 unfinished functions
Mat rgb2hsi(const Mat& rgb);  // converts RGB image to HSI space
Mat hsi2rgb(const Mat& hsi);  // converts HSI image to RGB space
Mat histogram(const Mat& im); // returns the histogram of the selected channel in HSI space
// void filter(Mat& im);//          // performs frequency-domain filtering on a single-channel image

int main(int argc, char* argv[])
{
    if (argc < 2) // check number of arguments
    {
        cerr << "feed me something!!" << endl; // no arguments passed
        return -1;
    }
    string path = argv[1];
    Mat im; // load an RGB image
    Mat hsi = rgb2hsi(im); // convert it to HSI space
    Mat slices[3]; // 3 channels of the converted HSI image
    im = imread(path); //try to load path
    if (im.empty()) // loaded Sucessfully
    {

        cerr << "I Cannot load the file : ";
            return -1;
    }
    imshow("BEFORE", im);

    split(hsi, slices); // split up the packed HSI image into an array of matrices

    Mat& h = slices[0];
    Mat& s = slices[1];
    Mat& i = slices[2]; // references to H, S, and I layers
    Mat hist1, hist2; // histogram of the selected channel before and after filtering

要应用直方图。可能是我错过了一些头球。没有抽签。

代码语言:javascript
复制
    Mat histogram(const Mat& im)
    {
        Mat hist;
        const float range[] = { 0, 255 };
        const int channels[] = { 0 };
        const int bins = range[1] - range[0];
        const int dims[] = { bins, 1 };
        const Size binSize(2, 240);
        const float* ranges[] = { range };

        // calculate the histogram
        calcHist(&im, 1, channels, Mat(), hist, 1, dims, ranges);

        Mat draw = Mat::zeros(binSize.height, binSize.width * bins, CV_8UC3);
        double maxVal;
        minMaxLoc(hist, NULL, &maxVal, 0, 0);

        for (int b = 0; b < bins; b++)
        {
            float val = hist.at<float>(b, 0);
            int x0 = binSize.width * b;
            int y0 = draw.rows - val / maxVal * binSize.height + 1;
            int x1 = binSize.width * (b + 1) - 1;
            int y1 = draw.rows - 1;

            rectangle(draw,0, cv::(Point(x0, y0), cv::Point(x1, y1)), Scalar::all(255), CV_FILLED);
        }

        return draw;
    }




imwrite("input-original.png", rgb); // write the input image
imwrite("hist-original.png", histogram(h)); // write the histogram of the selected channel
filter(h); // perform filtering
merge(slices, 3, hsi); // combine the separated H, S, and I layers to a big packed matrix
rgb = hsi2rgb(hsi); // convert HSI back to RGB colour space
imwrite("input-filtered.png", rgb); // write the filtered image
imwrite("hist-filtered.png", histogram(h)); // and the histogram of the filtered channel

return 0;
}



Mat rgb2hsi(const Mat& rgb)
{
    Mat slicesRGB[3];
    Mat slicesHSI[3];

    Mat &r = slicesRGB[0], &g = slicesRGB[1], &b = slicesRGB[2];
    Mat &h = slicesHSI[0], &s = slicesHSI[1], &i = slicesHSI[2];

    split(rgb, slicesRGB);

    //
    // TODO: implement colour conversion RGB => HSI
    //
    // begin of conversion code
    h = r * 1.0f;
    s = g * 1.0f;
    i = b * 1.0f;
    // end of conversion code

    Mat hsi;
    merge(slicesHSI, 3, hsi);

    return hsi;
}

Mat hsi2rgb(const Mat& hsi)
{
    Mat slicesRGB[3];
    Mat slicesHSI[3];

    Mat &r = slicesRGB[0], &g = slicesRGB[1], &b = slicesRGB[2];
    Mat &h = slicesHSI[0], &s = slicesHSI[1], &i = slicesHSI[2];

    split(hsi, slicesHSI);


    // begin of conversion code
    r = h * 1.0f;
    g = s * 1.0f;
    b = i * 1.0f;
    // end of conversion code

    Mat rgb;
    merge(slicesRGB, 3, rgb);

    return rgb;
}

Mat histogram(const Mat& im)
{
    Mat hist;
    const float range[] = { 0, 255 };
    const int channels[] = { 0 };
    const int bins = range[1] - range[0];
    const int dims[] = { bins, 1 };
    const Size binSize(2, 240);
    const float* ranges[] = { range };

    // calculate the histogram
    calcHist(&im, 1, channels, Mat(), hist, 1, dims, ranges);

    Mat draw = Mat::zeros(binSize.height, binSize.width * bins, CV_8UC3);
    double maxVal;
    minMaxLoc(hist, NULL, &maxVal, 0, 0);

    for (int b = 0; b < bins; b++)
    {
        float val = hist.at<float>(b, 0);
        int x0 = binSize.width * b;
        int y0 = draw.rows - val / maxVal * binSize.height + 1;
        int x1 = binSize.width * (b + 1) - 1;
        int y1 = draw.rows - 1;

        rectangle(draw, Point(x0, y0), Point(x1, y1), Scalar::all(255), CV_FILLED);
    }

    return draw;
}

void filter(Mat& im)
{
    int type = im.type();

    // Convert pixel data from unsigned 8-bit integers (0~255)
    //  to 32-bit floating numbers, as required by cv::dft
    if (type != CV_32F) im.convertTo(im, CV_32F);

    // Perform 2-D Discrete Fourier Transform
    Mat f;
    dft(im, f, DFT_COMPLEX_OUTPUT + DFT_SCALE); // do DFT

    // Separate the packed complex matrix to two matrices
    Mat complex[2];
    Mat& real = complex[0]; // the real part
    Mat& imag = complex[1]; // the imaginary part
    split(f, complex); // dft(im) => {real,imag}

    // Frequency domain filtering
    int xc = im.cols / 2; // find (xc,yc) the highest
    int yc = im.rows / 2; //  frequency component

    for (int y = 0; y < im.rows; y++) // go through each row..
    {
        for (int x = 0; x < im.cols; x++) // then through each column..
        {
            //
            // TODO: Design your formula here to decide if the component is
            //       discarded or kept.
            //
            if (false) // override this condition
            {
                real.at<float>(y, x) = 0;
                imag.at<float>(y, x) = 0;
            }
        }
    }

    // Pack the real and imaginary parts 
    //  back to the 2-channel matrix
    merge(complex, 2, f); // {real,imag} => f

    // Perform 2-D Inverse Discrete Fourier Transform
    idft(f, im, DFT_REAL_OUTPUT); // do iDFT

    // convert im back to it's original type
    im.convertTo(im, type);
}

错误列表

1 IntelliSense:预期a ';‘d:\709 Tutorial\Dibya_project\Dibya_project\Dibya_project.cpp 48 2 Dibya_project 2 IntelliSense:标识符“Dibya_project”是未定义的d:\709 Tutorial\Dibya_project\Dibya_project\Dibya_project.cpp 70 13 Dibya_project 3 IntelliSense:没有重载函数的实例“矩形”匹配参数列表参数类型为:(、int、cv::Scalar_、( int) d:\709 Tutorial\Dibya_project\Dibya_project\Dibya_project.cpp 72 4 Dibya_project 4 IntelliSense:期望标识符d:\709 Tutorial\Dibya_project\Dibya_project\Dibya_project.cpp 72 26 Dibya_project 5 IntelliSense:没有构造函数"cv::Point_::Point with _Tp=int“的实例与参数列表参数类型匹配如下:(,双Tutorial\Dibya_project\Dibya_project\Dibya_project.cpp (双_X) d:\709 __cdecl 72 27 Dibya_project

EN

回答 2

Stack Overflow用户

发布于 2015-04-25 16:23:59

(在Mat直方图(.)中):

代码语言:javascript
复制
rectangle(draw,0, cv::(Point(x0, y0), cv::Point(x1, y1)), Scalar::all(255), CV_FILLED);

应当是:

代码语言:javascript
复制
rectangle(draw,0, cv::Rect(Point(x0, y0), cv::Point(x1, y1)), Scalar::all(255), CV_FILLED);

或者:

代码语言:javascript
复制
rectangle(draw,0, Point(x0, y0), cv::Point(x1, y1), Scalar::all(255), CV_FILLED);
票数 0
EN

Stack Overflow用户

发布于 2017-08-25 16:46:40

我认为包含highgui头文件有一个错误。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29867324

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档