关于非常相似的直方图匹配

yi133128 2017-10-13 06:02:32
我有两张图,一张为背景图,一张为在此背景下摄像头采集的图像,需要将背景图像的亮度尽量调成采集图像的,采用HSV颜色模型,使背景图中的V通道下的直方图匹配采集图像中V通道下的直方图,但是我用GML匹配,效果很差,求大神门指点,是否是我这用的算法问题,还是直方图匹配本身达不到那样的效果,能有什么效果能达到我想要的效果吗?谢谢
其中的代码为
#include<cv.h>
#include <opencv2/opencv.hpp>
#include <highgui.h>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
using namespace std;
using namespace cv;


void myShowHist(int *psrccnt, string winname, int style = 0, int rows = 480, int cols = 640)
{
Mat hist(rows, cols, CV_8UC3, Scalar(0, 0, 0));

int maxcnt = psrccnt[0];


for (int i = 0; i <= 255; i++){
if (psrccnt[i] > maxcnt) maxcnt = psrccnt[i];
}


int lineType = 8;
if (style == 0) { //sticks
int thickness = 1;
for (int i = 0; i <= 255; i++){
if (psrccnt[i] != 0){
line(hist,
Point((int)((float)(i)*((float)cols / 256.0f)), rows),
Point((int)((float)(i)*((float)cols / 256.0f)), rows - (int)((float)psrccnt[i] * (float)rows / (float)maxcnt)),
Scalar(0, 255, 255), thickness, lineType);
//Scalar(0, 255, 255)线条颜色,thickness线条粗细,lineType线段的类型




}
}
}
else{ // continuous curve
int thickness = 2;
int i = 0;
int start = 0;
while (psrccnt[i] == 0)
{
start = i;
i++;
}
for (i = start + 1; i <= 255; i++) {
int cnt = psrccnt[i];
if (cnt != 0) {
line(hist,
Point((int)((float)(start)*((float)cols / 256.0f)), rows - (int)((float)psrccnt[start] * (float)rows / (float)maxcnt)),
Point((int)((float)i*((float)cols / 256.0f)), rows - (int)((float)cnt*(float)rows / (float)maxcnt)),
Scalar(0, 255, 255), thickness, lineType);
start = i;
}
}



}
imshow(winname, hist);

}

int main()
{
Mat image = imread("D:\\picture\\图像融合测试\\frame108.jpg", 1);
Mat src1 = imread("D:\\picture\\图像融合测试\\back.jpg", 1);

//得到HSV通道的histgram
Mat match1;
cvtColor(image, match1, CV_BGR2HSV);
Mat src_planes[] = { Mat::zeros(match1.size(), CV_8UC1), Mat::zeros(match1.size(), CV_8UC1), Mat::zeros(match1.size(), CV_8UC1) };
split(match1, src_planes);
Mat match = src_planes[2];

Mat src2;
cvtColor(src1, src2, CV_BGR2HSV);
Mat bg_planes[] = { Mat::zeros(src2.size(), CV_8UC1), Mat::zeros(src2.size(), CV_8UC1), Mat::zeros(src2.size(), CV_8UC1) };
split(src2, bg_planes);
Mat src = bg_planes[2];
Mat dst = Mat::zeros(src.size(), src.type());
Mat dst1 = Mat::zeros(src.size(), src.type());//存放匹配后的V直方图
Mat out_img(src2.rows, src2.cols, CV_8UC3); //用来存储目的图片的矩阵
Mat output_planes[3];


uchar eToDst[256] = { 0 };

int image_V_Hist[256] = { 0 };


//在匹配图像中不加上前景区域的V直方图
int image_V_Hist[256] = { 0 };
for (int j = 0; j <= 30; j++)
{
for (int i = 0; i <= match.cols; i++)
{
uchar grey = *(match.data + j*match.cols + i);
(image_V_Hist[grey])++;

}
}
for (int j = 478; j <= match.rows; j++)
{
for (int i = 0; i <= match.cols; i++)
{
uchar grey = *(match.data + j*match.cols + i);
(image_V_Hist[grey])++;

}
}
for (int j = 30; j <= 478; j++)
{
for (int i = 0; i <= 505; i++)
{
(image_V_Hist[match.ptr <uchar>(j)[i]])++;

}
}
for (int j = 30; j <= 478; j++)
{
for (int i = 950; i <= match.cols; i++)
{
(image_V_Hist[match.ptr <uchar>(j)[i]])++;

}
}

int CDF[256] = { 0 };
CDF[0] = image_V_Hist[0];

for (int i = 1; i <= 255; i++){
CDF[i] = CDF[i - 1] + image_V_Hist[i];
}

double matchguiyihua[256] = { 0 };
for (int i = 1; i <= 255; i++){
matchguiyihua[i] = (double)image_V_Hist[i] / CDF[255];
}

//get match CDF
double matchCDF[256] = { 0 };
matchCDF[0] = matchguiyihua[0];

for (int i = 1; i <= 255; i++){
matchCDF[i] = matchCDF[i - 1] + matchguiyihua[i];
}


//加上前景区域的直方图
int src_V_Hist[256] = { 0 };

//不加上前景区域的V直方图
for (int j = 0; j <= 30; j++)
{
for (int i = 0; i <= src.cols; i++)
{
uchar grey = *(src.data + j*src.cols + i);
(src_V_Hist[grey])++;

}
}
for (int j = 478; j <= src.rows; j++)
{
for (int i = 0; i <= src.cols; i++)
{
uchar grey = *(src.data + j*src.cols + i);
(src_V_Hist[grey])++;

}
}
for (int j = 30; j <= 478; j++)
{
for (int i = 0; i <= 505; i++)
{
(src_V_Hist[src.ptr <uchar>(j)[i]])++;

}
}
for (int j = 30; j <= 478; j++)
{
for (int i = 950; i <= src.cols; i++)
{
(src_V_Hist[src.ptr <uchar>(j)[i]])++;

}
}
int sCDF[256] = { 0 };
sCDF[0] = src_V_Hist[0];
for (int i = 1; i <= 255; i++){
sCDF[i] = sCDF[i - 1] + src_V_Hist[i];
}

double srcguiyihua[256] = { 0 };
for (int i = 1; i <= 255; i++){
srcguiyihua[i] = (double)src_V_Hist[i] / sCDF[255];
}

//get src CDF
double srcCDF[256] = { 0 };
srcCDF[0] = srcguiyihua[0];
for (int i = 1; i <= 255; i++){
srcCDF[i] = srcCDF[i - 1] + srcguiyihua[i];
}



//计算GML
int i, j;
double srcMin[256][256] = { 0 };
for (i = 0; i < 255; i++)
{
for (j = 0; j < 255; j++)
{
srcMin[j][i] = fabs(srcCDF[i] - matchCDF[j]);

}
}
short lastStartY = 0, lastEndY = 0, startY = 0, endY = 0;
for (j = 0; j < 255; j++)
{
double minValue = srcMin[j][0];
for (i = 0; i < 255; i++)
{
if (minValue>srcMin[j][i])
{
endY = i;
minValue = srcMin[j][i];
}
}
if (startY != lastStartY || endY != lastEndY)
{
for (int x = startY; x <= endY; x++)
eToDst[x] = j;
lastStartY = startY;
lastEndY = endY;
startY = lastEndY + 1;
}
}


for (int j = 0; j <= 30; j++)
{
for (int i = 0; i <= dst.cols; i++)
{
*(dst.data + j*dst.cols + i) = eToDst[*(src.data + j*src.cols + i)];

}
}
for (int j = 478; j <= dst.rows; j++)
{
for (int i = 0; i <= dst.cols; i++)
{
*(dst.data + j*dst.cols + i) = eToDst[*(src.data + j*src.cols + i)];
}
}
for (int j = 30; j <= 478; j++)
{
for (int i = 0; i <= 505; i++)
{
dst.ptr <uchar>(j)[i] = eToDst[src.ptr <uchar>(j)[i]];

}
}
for (int j = 30; j <= 478; j++)
{
for (int i = 950; i <= src.cols; i++)
{
dst.ptr <uchar>(j)[i] = eToDst[src.ptr <uchar>(j)[i]];

}
}


int dstHist[256] = { 0 };

for (int j = 0; j <= 30; j++)
{
for (int i = 0; i <= dst.cols; i++)
{
uchar grey = *(dst.data + j*dst.cols + i);
(dstHist[grey])++;

}
}
for (int j = 478; j <= dst.rows; j++)
{
for (int i = 0; i <= dst.cols; i++)
{
uchar grey = *(dst.data + j*dst.cols + i);
(dstHist[grey])++;

}
}
for (int j = 30; j <= 478; j++)
{
for (int i = 0; i <= 505; i++)
{
uchar grey = dst.ptr <uchar>(j)[i];
(dstHist[grey])++;
}
}
for (int j = 30; j <= 478; j++)
{
for (int i = 950; i <= src.cols; i++)
{
uchar grey = dst.ptr <uchar>(j)[i];
(dstHist[grey])++;

}
}



output_planes[0] = bg_planes[0];
output_planes[1] = bg_planes[1];
output_planes[2] = dst;//改变的是V通道,即亮度
merge(output_planes, 3, out_img); //通道合并
cvtColor(out_img, out_img, CV_HSV2BGR);

int dsthist[256] = { 0 };
namedWindow("zftdst");
imshow("zftdst", out_img);
namedWindow("zftmatch");
imshow("zftmatch", image);


myShowHist(image_V_Hist, "image_V_Hist");
myShowHist(src_V_Hist, "src_V_Hist");
myShowHist(dstHist, "dst_Hist");


waitKey();
return 0;
}
...全文
587 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

3,423

社区成员

发帖
与我相关
我的任务
社区描述
其他开发语言 其他开发语言
社区管理员
  • 其他开发语言社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧