|
|
@@ -6,4 +6,213 @@
|
|
|
// Copyright © 2019 Drew. All rights reserved.
|
|
|
//
|
|
|
|
|
|
-#include <stdio.h>
|
|
|
+#include "HSVFilter.h"
|
|
|
+
|
|
|
+namespace Adjust {
|
|
|
+ int h = 56, s = 190 , v = 255;
|
|
|
+
|
|
|
+ //输入图像
|
|
|
+ Mat img;
|
|
|
+ //灰度值归一化
|
|
|
+ Mat bgr;
|
|
|
+ //HSV图像
|
|
|
+ Mat hsv;
|
|
|
+ //色相
|
|
|
+ int hmin = 50;
|
|
|
+ int hmin_Max = 360;
|
|
|
+ int hmax = 130;
|
|
|
+ int hmax_Max = 360;
|
|
|
+ //饱和度
|
|
|
+ int smin = 40;
|
|
|
+ int smin_Max = 255;
|
|
|
+ int smax = 255;
|
|
|
+ int smax_Max = 255;
|
|
|
+ //亮度
|
|
|
+ int vmin = 130;
|
|
|
+ int vmin_Max = 255;
|
|
|
+ int vmax = 255;
|
|
|
+ int vmax_Max = 255;
|
|
|
+ //显示原图的窗口
|
|
|
+ string windowName = "src";
|
|
|
+ //输出图像的显示窗口
|
|
|
+ string dstName = "dst";
|
|
|
+ //输出图像
|
|
|
+ Mat dst;
|
|
|
+
|
|
|
+ void callBack(int, void*)
|
|
|
+ {
|
|
|
+ //输出图像分配内存
|
|
|
+ dst = Mat::zeros(img.size(), CV_32FC3);
|
|
|
+ //掩码
|
|
|
+ Mat mask;
|
|
|
+ inRange(hsv, Scalar(hmin, smin / float(smin_Max), vmin / float(vmin_Max)), Scalar(hmax, smax / float(smax_Max), vmax / float(vmax_Max)), mask);
|
|
|
+ //只保留
|
|
|
+ for (int r = 0; r < bgr.rows; r++)
|
|
|
+ {
|
|
|
+ for (int c = 0; c < bgr.cols; c++)
|
|
|
+ {
|
|
|
+ if (mask.at<uchar>(r, c) == 255)
|
|
|
+ {
|
|
|
+ // dst.at<Vec3f>(r, c) = bgr.at<Vec3f>(r, c);
|
|
|
+ dst.at<Vec3f>(r, c) = Vec3f(0,0,0);
|
|
|
+ } else {
|
|
|
+ dst.at<Vec3f>(r, c) = Vec3f(255,255,255);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //输出图像
|
|
|
+ putText(dst, "hmin"+to_string(hmin), Point(50,50), FONT_HERSHEY_COMPLEX, 1, Scalar(0,0,255));
|
|
|
+ putText(dst, "hmax"+to_string(hmax), Point(50,100), FONT_HERSHEY_COMPLEX, 1, Scalar(0,0,255));
|
|
|
+ putText(dst, "smin"+to_string(smin), Point(50,150), FONT_HERSHEY_COMPLEX, 1, Scalar(0,0,255));
|
|
|
+ putText(dst, "smax"+to_string(smax), Point(50,200), FONT_HERSHEY_COMPLEX, 1, Scalar(0,0,255));
|
|
|
+ putText(dst, "vmin"+to_string(vmin), Point(50,250), FONT_HERSHEY_COMPLEX, 1, Scalar(0,0,255));
|
|
|
+ putText(dst, "vmax"+to_string(vmax), Point(50,300), FONT_HERSHEY_COMPLEX, 1, Scalar(0,0,255));
|
|
|
+ imshow(dstName, dst);
|
|
|
+ //保存图像
|
|
|
+ dst.convertTo(dst, CV_8UC3, 255.0, 0);
|
|
|
+ imwrite("HSV_inRange.jpg", dst);
|
|
|
+ }
|
|
|
+ void adjust(string path)
|
|
|
+ {
|
|
|
+ //输入图像
|
|
|
+ img = imread(path, IMREAD_COLOR);
|
|
|
+ imshow(windowName, img);
|
|
|
+ blur(img, img, Size(3,3));
|
|
|
+ //彩色图像的灰度值归一化
|
|
|
+ img.convertTo(bgr, CV_32FC3, 1.0 / 255, 0);
|
|
|
+ //颜色空间转换
|
|
|
+ cvtColor(bgr, hsv, COLOR_BGR2HSV);
|
|
|
+ //定义输出图像的显示窗口
|
|
|
+ namedWindow(dstName, WINDOW_GUI_EXPANDED);
|
|
|
+ //调节色相 H
|
|
|
+ createTrackbar("hmin", dstName, &hmin, hmin_Max, callBack);
|
|
|
+ createTrackbar("hmax", dstName, &hmax, hmax_Max, callBack);
|
|
|
+ //调节饱和度 S
|
|
|
+ createTrackbar("smin", dstName, &smin, smin_Max, callBack);
|
|
|
+ createTrackbar("smax", dstName, &smax, smax_Max, callBack);
|
|
|
+ //调节亮度 V
|
|
|
+ createTrackbar("vmin", dstName, &vmin, vmin_Max, callBack);
|
|
|
+ createTrackbar("vmax", dstName, &vmax, vmax_Max, callBack);
|
|
|
+ callBack(0, 0);
|
|
|
+ waitKey(0);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+vector<MatND> getHSVHist(Mat &src){
|
|
|
+
|
|
|
+ //输入图片得是三通道彩色图片
|
|
|
+ assert (!src.empty() && src.channels() == 3);
|
|
|
+
|
|
|
+ //rgb转hsv图像
|
|
|
+ Mat hsv;
|
|
|
+ cvtColor(src, hsv, COLOR_BGR2HSV);
|
|
|
+
|
|
|
+ //h的范围是0~180,所以选取30个bin
|
|
|
+ //s和v的范围都是0~255,那就选择51个bin
|
|
|
+ int hbins = 30;
|
|
|
+ int sbins = 51;
|
|
|
+ int vbins = 51;
|
|
|
+ int hHistSize[] = {hbins};
|
|
|
+ int sHistSize[] = {sbins};
|
|
|
+ int vHistSize[] = {vbins};
|
|
|
+
|
|
|
+ float hranges[] = {0, 180};
|
|
|
+ float sranges[] = {0, 255};
|
|
|
+ float vranges[] = {0, 255};
|
|
|
+ const float* hRanges[] = {hranges};
|
|
|
+ const float* sRanges[] = {sranges};
|
|
|
+ const float* vRanges[] = {vranges};
|
|
|
+ vector<MatND> hist;
|
|
|
+
|
|
|
+ int hChannels[] = {0};
|
|
|
+ int sChannels[] = {1};
|
|
|
+ int vChannels[] = {2};
|
|
|
+ MatND hHist, sHist, vHist;
|
|
|
+ calcHist(&hsv, 1, hChannels, Mat(), hHist, 1, hHistSize, hRanges);
|
|
|
+ calcHist(&hsv, 1, sChannels, Mat(), sHist, 1, sHistSize, sRanges);
|
|
|
+ calcHist(&hsv, 1, vChannels, Mat(), vHist, 1, vHistSize, vRanges);
|
|
|
+ hist.push_back(hHist);
|
|
|
+ hist.push_back(sHist);
|
|
|
+ hist.push_back(vHist);
|
|
|
+ normalize( hist[0], hist[0], 0, 1, NORM_MINMAX, -1, Mat() );
|
|
|
+ normalize( hist[1], hist[1], 0, 1, NORM_MINMAX, -1, Mat() );
|
|
|
+ normalize( hist[2], hist[2], 0, 1, NORM_MINMAX, -1, Mat() );
|
|
|
+
|
|
|
+ int i;
|
|
|
+ int start = -1, end = -1;
|
|
|
+ for(i = 0; i < 30; i++)
|
|
|
+ {
|
|
|
+ float value = hist[0].at<float>(i);
|
|
|
+ if (value > 0)
|
|
|
+ {
|
|
|
+ if (start == -1)
|
|
|
+ {
|
|
|
+ start = i;
|
|
|
+ end = i;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ end = i;
|
|
|
+ cout << "H Value" << i << ": " << value << endl;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if (start != -1)
|
|
|
+ cout <<"H:" <<start*6 <<"~"<<(end+1)*6-1<<endl;
|
|
|
+ start = end = -1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (start != -1)
|
|
|
+ cout <<"H:" <<start*5 <<"~"<<(end+1)*5-1<<endl;
|
|
|
+
|
|
|
+ start = -1, end = -1;
|
|
|
+ for(i = 0; i < 51; i++)
|
|
|
+ {
|
|
|
+ float value = hist[1].at<float>(i);
|
|
|
+ if (value > 0)
|
|
|
+ {
|
|
|
+ if (start == -1)
|
|
|
+ {
|
|
|
+ start = i;
|
|
|
+ end = i;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ end = i;
|
|
|
+ cout << "S Value" << i << ": " << value << endl;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if (start != -1)
|
|
|
+ cout <<"S:"<< start*5 <<"~"<<(end+1)*5-1<<endl;
|
|
|
+ start = end = -1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (start != -1)
|
|
|
+ cout <<"S:" <<start*5 <<"~"<<(end+1)*5-1<<endl;
|
|
|
+
|
|
|
+ start = -1, end = -1;
|
|
|
+ for(i = 0; i < 51; i++)
|
|
|
+ {
|
|
|
+ float value = hist[2].at<float>(i);
|
|
|
+ if (value > 0)
|
|
|
+ {
|
|
|
+ if (start == -1)
|
|
|
+ {
|
|
|
+ start = i;
|
|
|
+ end = i;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ end = i;
|
|
|
+ cout << "V Value" << i << ": " << value << endl;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if (start != -1)
|
|
|
+ cout <<"V:" <<start*5 <<"~"<<(end+1)*5-1<<endl;
|
|
|
+ start = end = -1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (start != -1)
|
|
|
+ cout <<"V:" <<start*5 <<"~"<<(end+1)*5-1<<endl;
|
|
|
+
|
|
|
+ return hist;
|
|
|
+}
|