記事のディレクトリ
周囲:
Visual Studio 2019 + opencv3.3.1 + mathGL
問題の説明:
opencvのhist関数を組み合わせて自分で作成することもできますが、C ++でヒストグラムを作成するのは特に便利ではありません。自分で作成した関数の効果は次のとおりです。
一般的に、それはさらに厄介です。C++には視覚化ライブラリが少ないので、今日はMathGlを試してみましょう。
MathGLの構成:
MathGLの公式ドキュメントとチュートリアルを参照することもできます。
MathGl公式ドキュメント
チュートリアルのダウンロード
コードデモ:
コード:
#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
#include <algorithm>
#include <vector>
#include "mgl2/mgl.h"
using namespace std;
using namespace cv;
int my_hist(mglGraph* gr, Mat gray)
{
int histSize = 256; // 直方图bin的个数
float range[] = {
0, 256 }; // 输入数据的维度 灰度值范围为0-255
const float* histRanges = {
range };
Mat hist;
calcHist(&gray, 1, 0, Mat(), hist, 1, &histSize, &histRanges, true, false);
mglData y;
mglData* py = &y;
py->Create(256);
for (int i = 0; i < hist.rows; i++)
{
py->a[i] = hist.at<float>(i);
}
//y.Norm(mreal(0), mreal(1));
gr->SetRanges(0, 255, 0, y.Maximal());
gr->Axis(); // 坐标轴
gr->Box();
gr->Bars(y);
return 0;
}
int main(int argc, char** argv)
{
Mat src, dst;
src = imread("pictures/test.jpg", IMREAD_COLOR);//src 缩写为源文件 打开的文件名要加上格式 比如 jpg
if (src.empty())
{
printf("could not load image....\n");
return -1;//返回值为-1 表示异常
}
namedWindow("input", CV_WINDOW_AUTOSIZE);//创建一个窗口并命名
imshow("input", src);//在指定窗口显示指定图片
cvtColor(src, dst, COLOR_BGR2GRAY);
Mat hist_img = my_drawHist(dst);
//创建gr对象,指定图像大小为800x500,kind=0说明不使用OpenGL
mglGraph gr1(0, 800, 500);
my_hist(&gr1, dst);
//用OpenCV显示图片
Mat pic(gr1.GetHeight(), gr1.GetWidth(), CV_8UC3);
pic.data = const_cast<uchar*>(gr1.GetRGB());
imshow("test", pic);
//保存图片
std::cout << "write image as \"test.png\"." << std::endl;
gr.WritePNG("test.png"); // Don't forget to save the result!
waitKey(0);
return 0;
}
結果:
追記
mathGLはHist関数も提供します。
ただし、画像のヒストグラムを描画するだけの場合、この関数は必要ありません。公式ドキュメントに記載されています。
つまり、この関数は、ユーザーがランダムに定義した場合にのみ使用できます。データ(たとえば、xは乱数、yはxの関数です)。このとき、自動的にカウントするのに役立つHist関数を使用できます。
公式デモ:
void smgl_hist(mglGraph *gr)
{
mglData x(10000), y(10000), z(10000); gr->Fill(x,"2*rnd-1"); gr->Fill(y,"2*rnd-1"); gr->Fill(z,"exp(-6*(v^2+w^2))",x,y);
mglData xx=gr->Hist(x,z), yy=gr->Hist(y,z); xx.Norm(0,1); yy.Norm(0,1);
gr->MultiPlot(3,3,3,2,2,""); gr->SetRanges(-1,1,-1,1,0,1); gr->Box(); gr->Dots(x,y,z,"wyrRk");
gr->MultiPlot(3,3,0,2,1,""); gr->SetRanges(-1,1,0,1); gr->Box(); gr->Bars(xx);
gr->MultiPlot(3,3,5,1,2,""); gr->SetRanges(0,1,-1,1); gr->Box(); gr->Barh(yy);
gr->SubPlot(3,3,2); gr->Puts(mglPoint(0.5,0.5),"Hist and\nMultiPlot\nsample","a",-3);
}
結果: