该文档似乎没有解释HSV-> BGR转换的预期输入范围。这是一些示例代码,我试图在将其转换为HSV后恢复原始BGR值。有谁知道预期会有哪些缩放?
#include <iostream>
#include <opencv2/opencv.hpp>
cv::Vec3b HSVtoBGR(const cv::Vec3f& hsv)
{
cv::Vec3f hsvAdjusted = hsv; // If we use this directly, the output is (0,0,1) which is very wrong
//hsvAdjusted[0] *= 360.; // If we do this to bring all of the values into the range (0,1), the output is (0,1,0), which is also very wrong
// If we do this to bring all of the values into the range (0,255), the output is (0,0,200), which is still very wrong
hsvAdjusted[1] *= 255./360.;
hsvAdjusted[1] *= 255.;
hsvAdjusted[2] *= 255.;
cv::Mat_<cv::Vec3f> hsvMat(hsvAdjusted);
cv::Mat_<cv::Vec3f> bgrMat;
cv::cvtColor(hsvMat, bgrMat, CV_HSV2BGR);
cv::Vec3b bgr = static_cast<cv::Vec3b>(bgrMat(0,0));
return bgr;
}
/** Input 0 <= B <= 255, 0 <= G <= 255, 0 <= R <= 255
* Output 0 <= H <= 360, 0 <= S <= 1, 0 <= V <= 1 */
cv::Vec3f BGRtoHSV(const cv::Vec3b& bgr)
{
cv::Mat3f bgrMat(static_cast<cv::Vec3f>(bgr));
bgrMat *= 1./255.;
cv::Mat3f hsvMat;
cv::cvtColor(bgrMat, hsvMat, CV_BGR2HSV);
cv::Vec3f hsv = hsvMat(0,0);
return hsv;
}
int main()
{
// Create a BGR color
cv::Vec3b bgr(5, 100, 200);
std::cout << "bgr: " << bgr << std::endl;
// Convert BGR to HSV
cv::Vec3f hsv = BGRtoHSV(bgr);
std::cout << "hsv: " << hsv << std::endl; // outputs // (29.23, .976, .7843), which seems correct
// Convert back from HSV to BGR
cv::Vec3b bgr2 = HSVtoBGR(hsv);
std::cout << "bgr2: " << bgr2 << std::endl;
return 0;
}
答案 0 :(得分:2)
您在函数HSVtoBGR
中存在一些缩放问题。
转换后需要将结果乘以255,而不是之前。请注意,Mat
类型CV_32F
和CV_8U
的{{1}}会发生不同的转化。
这应该按预期工作:
cv::Vec3b HSVtoBGR(const cv::Vec3f& hsv)
{
cv::Mat_<cv::Vec3f> hsvMat(hsv);
cv::Mat_<cv::Vec3f> bgrMat;
cv::cvtColor(hsvMat, bgrMat, CV_HSV2BGR);
bgrMat *= 255; // Upscale after conversion
// Conversion to Vec3b is handled by OpenCV, no need to static_cast
return bgrMat(0);
}
答案 1 :(得分:0)
分别运行以下代码。您将能够控制RGB值并获得相应的HSV缩放。
#include<iostream>
#include<opencv2/core/core.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/highgui/highgui.hpp>
using namespace std;
using namespace cv;
char RGB_window[30] = "RGB Window";
char HSV_window[30] = "HSV Window";
Mat src,hsv;
static void onMouse( int event, int x, int y, int f, void* ){
Mat image=src.clone();
Vec3b rgb=image.at<Vec3b>(y,x);
int B=rgb.val[0];
int G=rgb.val[1];
int R=rgb.val[2];
Mat HSV;
Mat RGB=image(Rect(x,y,1,1));//capture that pixel in its own ROI
cvtColor(RGB, HSV,CV_BGR2HSV);
Vec3b hsv=HSV.at<Vec3b>(0,0);
int H=hsv.val[0];
int S=hsv.val[1];
int V=hsv.val[2];
char name[30];
sprintf(name,"B=%d",B);
putText(image,name, Point(150,40) , FONT_HERSHEY_SIMPLEX, .7, Scalar(0,255,0), 2,8,false );
sprintf(name,"G=%d",G);
putText(image,name, Point(150,80) , FONT_HERSHEY_SIMPLEX, .7, Scalar(0,255,0), 2,8,false );
sprintf(name,"R=%d",R);
putText(image,name, Point(150,120) , FONT_HERSHEY_SIMPLEX, .7, Scalar(0,255,0), 2,8,false );
sprintf(name,"H=%d",H);
putText(image,name, Point(25,40) , FONT_HERSHEY_SIMPLEX, .7, Scalar(0,255,0), 2,8,false );
sprintf(name,"S=%d",S);
putText(image,name, Point(25,80) , FONT_HERSHEY_SIMPLEX, .7, Scalar(0,255,0), 2,8,false );
sprintf(name,"V=%d",V);
putText(image,name, Point(25,120) , FONT_HERSHEY_SIMPLEX, .7, Scalar(0,255,0), 2,8,false );
sprintf(name,"X=%d",x);
putText(image,name, Point(25,300) , FONT_HERSHEY_SIMPLEX, .7, Scalar(0,0,255), 2,8,false );
sprintf(name,"Y=%d",y);
putText(image,name, Point(25,340) , FONT_HERSHEY_SIMPLEX, .7, Scalar(0,0,255), 2,8,false );
//namedWindow("Ref HSV",WINDOW_NORMAL);
Mat ref(50,50,CV_8UC3,Scalar(H,S,V));
//imwrite("hsv.jpg",image);
imshow( RGB_window, image );
//imshow( "Ref HSV",ref);
}
int main()
{
//VideoCapture cap(0);
static int Bs=0,Gs=0,Rs=0;
namedWindow("colourCtrl");
//src = imread("bgr.png",1);
for(;;)
{
//cap>>src;
createTrackbar("B","colourCtrl",&Bs,255);
createTrackbar("G","colourCtrl",&Gs,255);
createTrackbar("R","colourCtrl",&Rs,255);
Mat refRGB(500,500,CV_8UC3,Scalar(Bs,Gs,Rs));
src=refRGB;
cvtColor(src,hsv,CV_BGR2HSV);
imshow(RGB_window,src);
imshow(HSV_window,hsv);
setMouseCallback( RGB_window, onMouse, 0 );
setMouseCallback( HSV_window, onMouse, 0 );
char c=waitKey(10);
if(c=='b')
{break;}
}
return 0;
}