第一种:RGB color space
第二种:RG color space
第三种:Ycrcb之cr分量+otsu阈值化
第四种:YCrCb中133<=Cr<=173 77<=Cb<=127
第五种:HSV中 7<H<29
下一步需要滤波 *** 作 因为检测结果中有许多瑕疵
[cpp] view plain copy
#include "highguih"
#include "cvh"
// skin region location using rgb limitation
void SkinRGB(IplImage rgb,IplImage _dst)
{
assert(rgb->nChannels==3&& _dst->nChannels==3);
static const int R=2;
static const int G=1;
static const int B=0;
IplImage dst=cvCreateImage(cvGetSize(_dst),8,3);
cvZero(dst);
for (int h=0;h<rgb->height;h++) {
unsigned char prgb=(unsigned char)rgb->imageData+hrgb->widthStep;
unsigned char pdst=(unsigned char)dst->imageData+hdst->widthStep;
for (int w=0;w<rgb->width;w++) {
if ((prgb[R]>95 && prgb[G]>40 && prgb[B]>20 &&
prgb[R]-prgb[B]>15 && prgb[R]-prgb[G]>15/&&
!(prgb[R]>170&&prgb[G]>170&&prgb[B]>170)/)||//uniform illumination
(prgb[R]>200 && prgb[G]>210 && prgb[B]>170 &&
abs(prgb[R]-prgb[B])<=15 && prgb[R]>prgb[B]&& prgb[G]>prgb[B])//lateral illumination
) {
memcpy(pdst,prgb,3);
}
prgb+=3;
pdst+=3;
}
}
cvCopyImage(dst,_dst);
cvReleaseImage(&dst);
}
// skin detection in rg space
void cvSkinRG(IplImage rgb,IplImage gray)
{
assert(rgb->nChannels==3&&gray->nChannels==1);
const int R=2;
const int G=1;
const int B=0;
double Aup=-18423;
double Bup=15294;
double Cup=00422;
double Adown=-07279;
double Bdown=06066;
double Cdown=01766;
for (int h=0;h<rgb->height;h++) {
unsigned char pGray=(unsigned char)gray->imageData+hgray->widthStep;
unsigned char pRGB=(unsigned char )rgb->imageData+hrgb->widthStep;
for (int w=0;w<rgb->width;w++)
{
int s=pRGB[R]+pRGB[G]+pRGB[B];
double r=(double)pRGB[R]/s;
double g=(double)pRGB[G]/s;
double Gup=Auprr+Bupr+Cup;
double Gdown=Adownrr+Bdownr+Cdown;
double Wr=(r-033)(r-033)+(g-033)(g-033);
if (g<Gup && g>Gdown && Wr>0004)
{
pGray=255;
}
else
{
pGray=0;
}
pGray++;
pRGB+=3;
}
}
}
// implementation of otsu algorithm
// author: onezeros#yahoocn
// reference: Rafael C Gonzalez Digital Image Processing Using MATLAB
void cvThresholdOtsu(IplImage src, IplImage dst)
{
int height=src->height;
int width=src->width;
//histogram
float histogram[256]={0};
for(int i=0;i<height;i++) {
unsigned char p=(unsigned char)src->imageData+src->widthStepi;
for(int j=0;j<width;j++) {
histogram[p++]++;
}
}
//normalize histogram
int size=heightwidth;
for(int i=0;i<256;i++) {
histogram[i]=histogram[i]/size;
}
//average pixel value
float avgValue=0;
for(int i=0;i<256;i++) {
avgValue+=ihistogram[i];
}
int threshold;
float maxVariance=0;
float w=0,u=0;
for(int i=0;i<256;i++) {
w+=histogram[i];
u+=ihistogram[i];
float t=avgValuew-u;
float variance=tt/(w(1-w));
if(variance>maxVariance) {
maxVariance=variance;
threshold=i;
}
}
cvThreshold(src,dst,threshold,255,CV_THRESH_BINARY);
}
void cvSkinOtsu(IplImage src, IplImage dst)
{
assert(dst->nChannels==1&& src->nChannels==3);
IplImage ycrcb=cvCreateImage(cvGetSize(src),8,3);
IplImage cr=cvCreateImage(cvGetSize(src),8,1);
cvCvtColor(src,ycrcb,CV_BGR2YCrCb);
cvSplit(ycrcb,0,cr,0,0);
cvThresholdOtsu(cr,cr);
cvCopyImage(cr,dst);
cvReleaseImage(&cr);
cvReleaseImage(&ycrcb);
}
void cvSkinYUV(IplImage src,IplImage dst)
{
IplImage ycrcb=cvCreateImage(cvGetSize(src),8,3);
//IplImage cr=cvCreateImage(cvGetSize(src),8,1);
//IplImage cb=cvCreateImage(cvGetSize(src),8,1);
cvCvtColor(src,ycrcb,CV_BGR2YCrCb);
//cvSplit(ycrcb,0,cr,cb,0);
static const int Cb=2;
static const int Cr=1;
static const int Y=0;
//IplImage dst=cvCreateImage(cvGetSize(_dst),8,3);
cvZero(dst);
for (int h=0;h<src->height;h++) {
unsigned char pycrcb=(unsigned char)ycrcb->imageData+hycrcb->widthStep;
unsigned char psrc=(unsigned char)src->imageData+hsrc->widthStep;
unsigned char pdst=(unsigned char)dst->imageData+hdst->widthStep;
for (int w=0;w<src->width;w++) {
if (pycrcb[Cr]>=133&&pycrcb[Cr]<=173&&pycrcb[Cb]>=77&&pycrcb[Cb]<=127)
{
memcpy(pdst,psrc,3);
}
pycrcb+=3;
psrc+=3;
pdst+=3;
}
}
//cvCopyImage(dst,_dst);
//cvReleaseImage(&dst);
}
void cvSkinHSV(IplImage src,IplImage dst)
{
IplImage hsv=cvCreateImage(cvGetSize(src),8,3);
//IplImage cr=cvCreateImage(cvGetSize(src),8,1);
//IplImage cb=cvCreateImage(cvGetSize(src),8,1);
cvCvtColor(src,hsv,CV_BGR2HSV);
//cvSplit(ycrcb,0,cr,cb,0);
static const int V=2;
static const int S=1;
static const int H=0;
//IplImage dst=cvCreateImage(cvGetSize(_dst),8,3);
cvZero(dst);
for (int h=0;h<src->height;h++) {
unsigned char phsv=(unsigned char)hsv->imageData+hhsv->widthStep;
unsigned char psrc=(unsigned char)src->imageData+hsrc->widthStep;
unsigned char pdst=(unsigned char)dst->imageData+hdst->widthStep;
for (int w=0;w<src->width;w++) {
if (phsv[H]>=7&&phsv[H]<=29)
{
memcpy(pdst,psrc,3);
}
phsv+=3;
psrc+=3;
pdst+=3;
}
}
//cvCopyImage(dst,_dst);
//cvReleaseImage(&dst);
}
int main()
{
IplImage img= cvLoadImage("D:/skinjpg"); //随便放一张jpg在D盘或另行设置目录
IplImage dstRGB=cvCreateImage(cvGetSize(img),8,3);
IplImage dstRG=cvCreateImage(cvGetSize(img),8,1);
IplImage dst_crotsu=cvCreateImage(cvGetSize(img),8,1);
IplImage dst_YUV=cvCreateImage(cvGetSize(img),8,3);
IplImage dst_HSV=cvCreateImage(cvGetSize(img),8,3);
cvNamedWindow("inputimage", CV_WINDOW_AUTOSIZE);
cvShowImage("inputimage", img);
cvWaitKey(0);
SkinRGB(img,dstRGB);
cvNamedWindow("outputimage1", CV_WINDOW_AUTOSIZE);
cvShowImage("outputimage1", dstRGB);
cvWaitKey(0);
cvSkinRG(img,dstRG);
cvNamedWindow("outputimage2", CV_WINDOW_AUTOSIZE);
cvShowImage("outputimage2", dstRG);
cvWaitKey(0);
cvSkinOtsu(img,dst_crotsu);
cvNamedWindow("outputimage3", CV_WINDOW_AUTOSIZE);
cvShowImage("outputimage3", dst_crotsu);
cvWaitKey(0);
cvSkinYUV(img,dst_YUV);
cvNamedWindow("outputimage4", CV_WINDOW_AUTOSIZE);
cvShowImage("outputimage4", dst_YUV);
cvWaitKey(0);
cvSkinHSV(img,dst_HSV);
cvNamedWindow("outputimage5", CV_WINDOW_AUTOSIZE);
cvShowImage("outputimage5", dst_HSV);
cvWaitKey(0);
return 0;
}
OpenCV是一个开源的图像处理库,QML是Qt官方推出的一个描述性语言,QtMarkupLanguage,QtQuick也是Qt官方推出的一个技术框架,在开发嵌入式、动态触屏等时有一定的优势。
模块的作用:
打一个很简单的比方,QML就是Qt的HTML,C就是Qt的JavaScript,而QtQuick相当于一些已经集成好的开发框架,使开发应用程序变得更加简单省事。
OpenCV是一个基于C/C的开源图像处理库,和Qt本身没有太多关联,其主要是用于计算机视觉和图形开发,Qt的扩展应用OpenCV并不是每个应用程序都要用到,只是某些有特殊需求的应用程序可以更方便地使用Qt扩展的OpenCV应用。比如说用Qt开发一个软件,要使用人脸识别功能,就可以集成OpenCV来实现。
使用频率:
虽然说QML相当于HTML,C相当于JavaScript,但是还是有一定区别:所有的网页都是通过解析HTML渲染出的,JavaScript虽然可以动态改变网页,但是最终还是通过改变HTML来达到效果;QML、C的关系恰好反过来,在Qt中,C是“更加底层”的,QML使用更加简单的标记语言的语法来调用底层的C绘图支持API,从而提高程序开发的效率。
使用QML可以更快速、简捷地开发应用程序,在Qt中的使用频率也是很高的,不过这要根据特定开发人群、开发目标而定。有些开发者习惯直接使用C开发,而有些开发者更喜欢简单的QML,很多时候都是“用QML开发用户界面,用C开发业务逻辑”,但是用C开发用户界面的也不在少数。
QtQuick是一套开发框架,核心语言就是QML。
QtQuick的使用频率不低,从Qt的NewProject界面就可以看出,QtQuick是和Qt传统的CWidge平起平坐的(当然还有QtforPython等)。
OpenCV在不需要图形处理功能的情况下是不需要用到的,所以不怎么好说“使用频率”,因为这是针对特定的软件需求来的。
是否有必要学习:
QtQuick能够使应用程序开发更有效率,但是并不是开发一个程序必备的,能用QtQuick开发的,C肯定能够做出来,但是耗费时间、精力更多。在Qt开发工作这一块,掌握Qt的核心功能是必须的,而且这还远远不够。在招聘的时候肯定是考察应聘者对Qt各种技术和开发思想的理解和掌握情况,而QtQuick是官方推出的框架,掌握其开发方法应该是基本功。
以上就是关于opencv访问像素程序中这句话怎么理解(uchar*)src->imageData + i*src->width全部的内容,包括:opencv访问像素程序中这句话怎么理解(uchar*)src->imageData + i*src->width、OpenCV_opencv毛星云、等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)