彩色图像透明直方图显示

对视频流中的图像数据,提取其R、G、B分量值,生成彩色直方图,并设置直方图的透明度,将其显示在原图像上。

需要用到的关键方法如下:

1、将输入的直方图数据绘制在初始分辨率为256*64的图像上,图像大小可自行调整

// draw the histogram IplImage* DrawHistogram(CvHistogram *hist, float scaleX = 1, float scaleY = 1) { // Find the maximum value of the histogram to scale // other values accordingly float histMax = 0; cvGetMinMaxHistValue(hist, 0, &histMax, 0, 0); // Create a new blank image based on scaleX and scaleY IplImage* imgHist = cvCreateImage(cvSize(256*scaleX, 64*scaleY), 8 ,1); cvZero(imgHist); // Go through each bin for(int i=0;i<255;i++) { float histValue = cvQueryHistValue_1D(hist, i); // Get value for the current bin... float nextValue = cvQueryHistValue_1D(hist, i+1); // ... and the next bin // Calculate the four points of the polygon that these two // bins enclose CvPoint pt1 = cvPoint(i*scaleX, 64*scaleY); CvPoint pt2 = cvPoint(i*scaleX+scaleX, 64*scaleY); CvPoint pt3 = cvPoint(i*scaleX+scaleX, (64-nextValue*64/histMax)*scaleY); CvPoint pt4 = cvPoint(i*scaleX, (64-histValue*64/histMax)*scaleY); // A close convex polygon int numPts = 5; CvPoint pts[] = {pt1, pt2, pt3, pt4, pt1}; // Draw it to the image cvFillConvexPoly(imgHist, pts, numPts, cvScalar(255)); } // Return it... make sure you delete it once you're done! return imgHist; }

2、将覆盖图像放置在源图像的指定位置上,并设置混合系数

// set an overlay image on to the src image void OverlayImage(IplImage *src, IplImage *overlay, CvPoint location, CvScalar S, CvScalar D) { int overlayWidth = overlay->width; int overlayHeight = overlay->height; int srcWidth = src->width; int srcHeight = src->height; for (int x = 0; x < overlayWidth; x++) { if (x + location.x >= srcWidth) break; for (int y = 0; y < overlayHeight; y++) { if (y + location.y >= srcHeight) continue; // calculate merged pixel value CvScalar source = cvGet2D(src, y + location.y, x + location.x); CvScalar over = cvGet2D(overlay, y, x); CvScalar merged; for (int indexk = 0; indexk < 4; indexk++) merged.val[indexk] = (S.val[indexk] * source.val[indexk] + D.val[indexk] * over.val[indexk]); // set new pixel value on image src cvSet2D(src, y + location.y, x + location.x, merged); } } }

 

程序流程:

1、通过Opencv提供的第三方库videoInput在windows平台下利用DirectShow接口告诉的获取视频流;

videoInput vi; int numDevices = vi.listDevices(); int device = 0; // setup device vi.setupDevice(device); if (!vi.isDeviceSetup(device)) { printf("Could not initializing capture device.../n"); return -1; } int width = vi.getWidth(device); int height = vi.getHeight(device);

2、创建图像,以暂存每一帧的视频数据;

// hold camera video feed IplImage *image = cvCreateImage(cvSize(width, height), 8, 3);

3、创建CV_HIST_ARRAY类型的一维直方图;

// for histograms int numBins = 256; float range[] = {0, 255}; float *ranges[] = {range}; // create histogram CvHistogram *hist = cvCreateHist(1, &numBins, CV_HIST_ARRAY, ranges, 1); cvClearHist(hist);

4、创建用于构建三通道彩色直方图的黑色背景图像;

IplImage *imgBlack = cvCreateImage(cvSize(128, 32), 8, 1); cvZero(imgBlack);

5、创建暂存视频流当前帧的红、绿、蓝分量的图像以及用于显示彩色直方图的图像;

IplImage* imgRed = cvCreateImage(cvGetSize(image), 8, 1); IplImage* imgGreen = cvCreateImage(cvGetSize(image), 8, 1); IplImage* imgBlue = cvCreateImage(cvGetSize(image), 8, 1); IplImage* imgRedHist = cvCreateImage(cvSize(128, 32), 8, 3); IplImage* imgGreenHist = cvCreateImage(cvSize(128, 32), 8, 3); IplImage* imgBlueHist = cvCreateImage(cvSize(128, 32), 8, 3);

6、进入程序主循环,提取当前帧的R、G、B分量;

int key;

cvNamedWindow("Overlay"); cvNamedWindow("HistRed"); cvNamedWindow("HistRedOnly"); cvNamedWindow("HistGreen"); cvNamedWindow("HistGreenOnly"); cvNamedWindow("HistBlue"); cvNamedWindow("HistBlueOnly");

while (1) { if (vi.isFrameNew(device)) { vi.getPixels(device, (unsigned char *)image->imageData, false, true); } cvSplit(image, imgBlue, imgGreen, imgRed, NULL);

7、分别计算R、G、B分量对应的直方图,并将其绘制在图像上,返回给调用者;

// calculate histograms for r,g,b images cvCalcHist(&imgRed, hist, 0, 0); // Calculate the histogram for red IplImage* imgHistRedOnly = DrawHistogram(hist, 0.5, 0.5); // Draw it cvClearHist(hist); // Clear the histgoram cvCalcHist(&imgGreen, hist, 0, 0); // Reuse it to calculate histogram for green IplImage* imgHistGreenOnly = DrawHistogram(hist, 0.5, 0.5); cvClearHist(hist); cvCalcHist(&imgBlue, hist, 0, 0); // And again for blue IplImage* imgHistBlueOnly = DrawHistogram(hist, 0.5, 0.5); cvClearHist(hist);

8、制作纯色直方图图像;

cvZero(imgRedHist); cvZero(imgGreenHist); cvZero(imgBlueHist); // merge the current histogram image into 3 channel image // 制作纯色(红、绿、蓝)的直方图图像 cvMerge(imgHistBlueOnly, imgBlack, imgBlack, NULL, imgBlueHist); cvMerge(imgBlack, imgHistGreenOnly, imgBlack, NULL, imgGreenHist); cvMerge(imgBlack, imgBlack, imgHistRedOnly, NULL, imgRedHist);

9、设置直方图图像在当前帧上的显示位置和透明度;

// set overlay image onto src image // 设置overley图像的透明度 //cvScalar(1,1,1,1); //cvScalar(0,0,0,0); OverlayImage(image, imgRedHist, cvPoint(48, 24), cvScalar(1,1,1,1), cvScalar(1,1,1,1)); OverlayImage(image, imgGreenHist, cvPoint(48, 76), cvScalar(1,1,1,1), cvScalar(1,1,1,1)); OverlayImage(image, imgBlueHist, cvPoint(48, 128), cvScalar(1,1,1,1), cvScalar(1,1,1,1));

10、显示直方图图像和透明处理后的当前帧,并释放临时申请的内存空间,以防止内存泄露;

cvShowImage("Overlay", image); cvShowImage("HistRed", imgRedHist); cvShowImage("HistRedOnly", imgHistRedOnly); cvShowImage("HistGreen", imgGreenHist); cvShowImage("HistGreenOnly", imgHistGreenOnly); cvShowImage("HistBlue", imgBlueHist); cvShowImage("HistBlueOnly", imgHistBlueOnly); key = cvWaitKey(15); if (key == 27) break;


// release images cvReleaseImage(&imgHistRedOnly); cvReleaseImage(&imgHistGreenOnly); cvReleaseImage(&imgHistBlueOnly);

}

11、释放创建的直方图对象和窗口对象,并关闭视频捕捉设备;

cvReleaseHist(&hist); cvDestroyWindow("Overlay"); cvDestroyWindow("HistRed"); cvDestroyWindow("HistGreen"); cvDestroyWindow("HistBlue"); cvDestroyWindow("HistRedOnly"); cvDestroyWindow("HistGreenOnly"); cvDestroyWindow("HistBlueOnly"); vi.stopDevice(device);

 

转自:http://www.aishack.in/2010/07/transparent-image-overlays-in-opencv/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值