opencv调节图像色相、饱和度、明度(H\S\V)
2015-11-10 11:04
423 查看
一、环境
1、Qt5.5.1;
2、opencv3.0;
3、visual studio 2013.
二、核心代码
1、图像处理部分
2、类型转换
1、Qt5.5.1;
2、opencv3.0;
3、visual studio 2013.
二、核心代码
1、图像处理部分
//调节图像的色相、饱和度、明度 bool CvImageAdjust::AddHSV(const QImage& inImg, QImage& outImg, double dH, double dS, double dV) { bool bResult = false; QImage imgSrc = inImg.copy(); IplImage *lImage = CImageConvert::ConvertToIplImage(imgSrc); cvCvtColor(lImage, lImage, CV_BGR2HSV); int i; uchar lut[256][3]; CvMat* lut_mat; lut_mat = cvCreateMatHeader(1, 256, CV_8UC3); cvSetData(lut_mat, lut, 0); for (i = 0; i < 256; i++) { int h = (i + dH); if (h > 180) { h -= 180; } else if (h < 0) { h += 180; } int s = (i + dS); if (s < 0) s = 0; if (s > 255) s = 255; int v = (i + dV); if (v < 0) v = 0; if (v > 255) v = 255; lut[i][0] = (uchar)h; lut[i][1] = (uchar)s; lut[i][2] = (uchar)v; } cvLUT(lImage, lImage, lut_mat); cvCvtColor(lImage, lImage, CV_HSV2BGR); QImage imgRult = CImageConvert::ConvertToQImage(lImage); CImageConvert::AddAlpha(inImg, imgRult); outImg = imgRult; cvReleaseImage(&lImage); bResult = true; return bResult; } //自动调节图片色彩到目标值,取出H\S\V值 bool CvImageAdjust::AutoAdjustHsv(QImage& imgGoal, QImage& img_ave, double& dH, double& dS, double& dV) { if (imgGoal.width() <= 0 || imgGoal.height() <= 0 || img_ave.width() <= 0 || img_ave.height() <= 0) { return false; } //创建AVG_S QImage avgImage(QSize(1, 1), QImage::Format_ARGB32); QRgb rgb = imgGoal.pixel(82 / 512.0 * imgGoal.width(), 162 / 512.0 * imgGoal.height()); avgImage.setPixel(0, 0, rgb); //计算参考H,S,L值 int H_src, S_src, L_src; CImageConvert::RGB2HSL_INT(qRed(rgb), qGreen(rgb), qBlue(rgb), H_src, S_src, L_src); //循环查找适当的HSV增量 int nH, nS, nV; nH = nS = nV = 0; for (int i = 0; i < 200; ++i) { int H_cur, S_cur, L_cur; QImage imgtemp; AddHSV(img_ave,imgtemp, nH, nS, nV); QRgb rgb = imgtemp.pixel(0, 0); CImageConvert::RGB2HSL_INT(qRed(rgb), qGreen(rgb), qBlue(rgb), H_cur, S_cur, L_cur); // int ic; if (L_src > L_cur) { ic = 1; } else { ic = -1; } int errLast = abs(L_cur - L_src); for (; nV <= 255 && nV >= -255; nV += ic) { QImage imgtemp; AddHSV(img_ave, imgtemp, nH, nS, nV); QRgb rgb = imgtemp.pixel(0, 0); CImageConvert::RGB2HSL_INT(qRed(rgb), qGreen(rgb), qBlue(rgb), H_cur, S_cur, L_cur); int errCur = abs(L_cur - L_src); if (errCur > errLast) { QImage imgtemp; AddHSV(img_ave, imgtemp, nH, nS, nV -= ic); QRgb rgb = imgtemp.pixel(0, 0); CImageConvert::RGB2HSL_INT(qRed(rgb), qGreen(rgb), qBlue(rgb), H_cur, S_cur, L_cur); errCur = abs(L_cur - L_src); break; } errLast = errCur; } // if (H_src > H_cur) { ic = 1; } else { ic = -1; } errLast = abs(H_cur - H_src); for (; nH <= 180 && nH >= -180; nH += ic) { QImage imgtemp; AddHSV(img_ave, imgtemp, nH, nS, nV); QRgb rgb = imgtemp.pixel(0, 0); CImageConvert::RGB2HSL_INT(qRed(rgb), qGreen(rgb), qBlue(rgb), H_cur, S_cur, L_cur); int errCur = abs(H_cur - H_src); if (errCur > errLast) { QImage imgtemp; AddHSV(img_ave, imgtemp, nH -= ic, nS, nV); QRgb rgb = imgtemp.pixel(0, 0); CImageConvert::RGB2HSL_INT(qRed(rgb), qGreen(rgb), qBlue(rgb), H_cur, S_cur, L_cur); errCur = abs(H_cur - H_src); break; } errLast = errCur; } // if (S_src > S_cur) { ic = 1; } else { ic = -1; } errLast = abs(S_cur - S_src); for (; nS <= 255 && nS >= -255; nS += ic) { QImage imgtemp; AddHSV(img_ave, imgtemp, nH, nS, nV); QRgb rgb = imgtemp.pixel(0, 0); CImageConvert::RGB2HSL_INT(qRed(rgb), qGreen(rgb), qBlue(rgb), H_cur 4000 , S_cur, L_cur); int errCur = abs(S_cur - S_src); if (errCur > errLast) { QImage imgtemp; AddHSV(img_ave, imgtemp, nH, nS -= ic, nV); QRgb rgb = imgtemp.pixel(0, 0); CImageConvert::RGB2HSL_INT(qRed(rgb), qGreen(rgb), qBlue(rgb), H_cur, S_cur, L_cur); errCur = abs(S_cur - S_src); break; } errLast = errCur; } if (abs(H_cur - H_src) <= 3 && abs(L_cur - L_src) <= 3) { break; } } dH = nH; dS = nS; dV = nV; return true; }
2、类型转换
#include <highgui.h> #include <opencv.h> //QImage->IplImage * IplImage *CImageConvert::ConvertToIplImage(const QImage &img) { /*int nChannel = 0; if (img.format() == QImage::Format_RGB888)nChannel = 3; if (img.format() == QImage::Format_ARGB32)nChannel = 4; if (nChannel == 0)return false; IplImage *iplImg = cvCreateImageHeader(cvSize(img.width(), img.height()), 8, nChannel); iplImg->imageData = (char*)img.bits(); if (nChannel == 3) cvConvertImage(iplImg, iplImg, CV_CVTIMG_SWAP_RB); return iplImg;*/ int width = img.width(); int height = img.height(); CvSize Size; Size.height = height; Size.width = width; IplImage *IplImageBuffer = cvCreateImage(Size, IPL_DEPTH_8U, 3); for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x) { QRgb rgb = img.pixel(x, y); cvSet2D(IplImageBuffer, y, x, CV_RGB(qRed(rgb), qGreen(rgb), qBlue(rgb))); } } return IplImageBuffer; } //Mat->QImage QImage CImageConvert::ConvertToQImage(cv::Mat &mat) { QImage img; int nChannel = mat.channels(); if (nChannel == 3) { cv::cvtColor(mat, mat, CV_BGR2RGB); return QImage((const unsigned char*)mat.data, mat.cols, mat.rows, QImage::Format_RGB888); } else if (nChannel == 4 || nChannel == 1) { return QImage((const unsigned char*)mat.data, mat.cols, mat.rows, QImage::Format_ARGB32); } return img; } //IplImage *->QImage QImage CImageConvert::ConvertToQImage(IplImage *iplImg) { QImage img; int nChannel = iplImg->nChannels; if (nChannel == 3) { cvConvertImage(iplImg, iplImg, CV_CVTIMG_SWAP_RB); return QImage((const unsigned char*)iplImg->imageData, iplImg->width, iplImg->height, QImage::Format_RGB888); } else if (nChannel == 4 || nChannel == 1) { return QImage((const unsigned char*)iplImg->imageData, iplImg->width, iplImg->height, QImage::Format_ARGB32); } return img; } //R, G, B:[0..255],integer //H:[0, 360),double, degrees around color circle //S:[0, 1], double, 0(shade of gray) to 1(pure color) //V:[0, 1], double, 0(black) to 1(white) void RGB2HSV(int R, int G, int B, double &H, double &S, double &V) { int Max = std::max(std::max(R, G), B); int Min = std::min(std::min(R, G), B); int Delta = Max - Min; if (Max == 0) S = 0.0; else S = (double)Delta / Max; if (abs(S) < FLT_EPSILON) H = 0.0; //当S为0时,H无意义, 但可以指定为0 else { if (R == Max) //yellow to magenta H = 60 * (G - B) / Delta; else if (G == Max) //cyan to yellow H = 120 + 60 * (B - R) / Delta; else if (B == Max) //magenta to cyan H = 240 + 60 * (R - G) / Delta; } if (H<0.0) H = 360.0 + H; if (H>360.0) H -= 360; V = Max / 255.0; } void RGB2HSL(int r, int g, int b, double &H, double &S, double &L) { double R, G, B, Max, Min, del_R, del_G, del_B, del_Max; R = r / 255.0; //Where RGB values = 0 ÷ 255 G = g / 255.0; B = b / 255.0; // Min = std::min(R, std::min(G, B)); //Min. value of RGB Max = std::max(R, std::max(G, B)); //Max. value of RGB del_Max = Max - Min; //Delta RGB value // L = (Max + Min) / 2.0; // if (del_Max == 0) //This is a gray, no chroma... { //H = 2.0/3.0; //Windows下S值为0时,H值始终为160(2/3*240) H = 0; //HSL results = 0 ÷ 1 S = 0; } else //Chromatic data... { if (L < 0.5) S = del_Max / (Max + Min); else S = del_Max / (2 - Max - Min); // del_R = (((Max - R) / 6.0) + (del_Max / 2.0)) / del_Max; del_G = (((Max - G) / 6.0) + (del_Max / 2.0)) / del_Max; del_B = (((Max - B) / 6.0) + (del_Max / 2.0)) / del_Max; // if (R == Max) H = del_B - del_G; else if (G == Max) H = (1.0 / 3.0) + del_R - del_B; else if (B == Max) H = (2.0 / 3.0) + del_G - del_R; // if (H < 0) H += 1; if (H > 1) H -= 1; } } void CImageConvert::RGB2HSL_INT(int r, int g, int b, int &H, int &S, int &L) { double h, s, l; RGB2HSV(r, g, b, h, s, l); /*H = (h * 255) + 0.5; S = (s * 255) + 0.5; L = (l * 255) + 0.5;*/ H = h; S = s; L = l; } //设置原始的Alpha通道 void CImageConvert::AddAlpha(const QImage &src, QImage &dest) { if (src.width() != dest.width() || src.height() != dest.height()) { return; } dest.setAlphaChannel(src. b46b alphaChannel()); }
相关文章推荐
- QT学习 第一章:基本对话框
- 使用Shiboken为C++和Qt库创建Python绑定
- PHP GD 图像处理组件的常用函数总结
- PHP图像处理之imagecreate、imagedestroy函数介绍
- Qt定时器和随机数详解
- jsvascript图像处理―(计算机视觉应用)图像金字塔
- Javascript图像处理思路及实现代码
- python中使用OpenCV进行人脸检测的例子
- opencv 做人脸识别 opencv 人脸匹配分析
- 使用opencv拉伸图像扩大分辨率示例
- Qt实现图片移动实例(图文教程)
- PHP图像处理之使用imagecolorallocate()函数设置颜色例子
- java数字图像处理基础使用imageio写图像文件示例
- 使用Java进行图像处理的一些基础操作
- javascript图像处理―边缘梯度计算函数
- Javascript图像处理―阈值函数实例应用
- Javascript图像处理―虚拟边缘介绍及使用方法
- Qt for Android开发实例教程
- OpenCV 2.4.3 C++ 平滑处理分析
- PHP图像处理类库及演示分享