一步步实现看图工具(四)


今天加入了一些新功能:

1. YUV文件格式支持(yuv420p 420sp, yuv422, yuv444) 

2. 亮度,色调,饱和度,对比度的调整。

3. 反色,灰度,阈值化操作。

4. 加入历史记录,以支持回退、前进等操作。

5. LOG模块和快捷键等等。

YUV文件格式支持

   不了解YUV格式的同学可以先看看这个:

   http://zh.wikipedia.org/wiki/YUV

   Opencv提供了YUV的转换函数, 但是色彩会有些损失。所以根据公式自己写了一个。 我这个是最近邻插值算法,相对于双线性或者双三次插值比较简单。 感兴趣的读者也可以自己实现。

void _YUVtoBGR(Vec3b& rgb, const Vec3b& yuv)
{
	int Y = yuv[0];
	int U = yuv[1] - 128;
	int V = yuv[2] - 128;

	int R = (int)( Y + 1.403f * V);
	int G = (int)( Y - 0.344f * U - 0.714f * V);
	int B = (int)( Y + 1.770f * U);

	rgb[0]= saturate_cast<uchar>(B);
	rgb[1]= saturate_cast<uchar>(G);
	rgb[2]= saturate_cast<uchar>(R);
}
void _BGRtoYUV(const Vec3b& rgb, Vec3b& yuv)
{
	int B = rgb[0];
	int G = rgb[1];
	int R = rgb[2];
	int Y = (int)(0.299f * R + 0.587f * G + 0.114f * B);
	int U = (int)((B-Y) * 0.565f + 128);
	int V = (int)((R-Y) * 0.713f + 128);

	yuv[0]= saturate_cast<uchar>(Y);
	yuv[1]= saturate_cast<uchar>(U);
	yuv[2]= saturate_cast<uchar>(V);
}


void ImageYUV2BGR(Mat& img, PBYTE pYUV, int type)
{
	CFunctionLog fl(__FUNCTION__);
	int w = img.cols;
	int h = img.rows;
	w = ALIGN_DOWN(w, 4);
	h = ALIGN_DOWN(h, 4);
	Vec3b yuv;
	switch(type)
	{
	case YUV_NV21:
	case YUV_NV12:
		{
			PBYTE pUV = pYUV+w*h;
			PBYTE pY = pYUV;
			int vidx = type == YUV_NV12 ? 1 : 2;
			int uidx = type == YUV_NV12 ? 2 : 1;
			for (int y = 0;y < h;y++)
			{
				for (int x = 0;x < w;x++)
				{
					yuv[0] = *pY++;
					yuv[uidx] = pUV[y/2*w+x/2*2];
					yuv[vidx] = pUV[y/2*w+x/2*2+1];
					_YUVtoBGR(img.at<Vec3b>(y, x), yuv);
				}
			}
		}
		break;
	case YUV_I420:
	case YUV_YV12:
		{
			PBYTE pY = pYUV;
			PBYTE pV = pYUV+w*h*5/4;
			PBYTE pU = pYUV+w*h;
			int uidx = type == YUV_I420 ? 1 : 2;
			int vidx = type == YUV_I420 ? 2 : 1;
			for (int y = 0;y < h;y++)
			{
				for (int x = 0;x < w;x++)
				{
					yuv[0] = *pY++;

					yuv[uidx] = pU[y/4*w+x/2+w*y/4%2];
					yuv[vidx] = pV[y/4*w+x/2+w*y/4%2];

					_YUVtoBGR(img.at<Vec3b>(y, x), yuv);

				}
			}
		}
		break;
	case YUV_YUYV:
	case YUV_UYVY:
		{
			int yidx = type == YUV_YUYV ? 0 : 1;
			int uidx = type == YUV_YUYV ? 1 : 0;
			int vidx = type == YUV_YUYV ? 3 : 2;
			PBYTE pY = pYUV + yidx;
			PBYTE pV = pYUV + vidx;
			PBYTE pU = pYUV + uidx;


			for (int y = 0;y < h;y++)
			{
				for (int x = 0;x < w;x++)
				{
					yuv[0] = *pY;
					pY+=2;
					if(x%2==0) {
						yuv[1] = *pU;
						yuv[2] = *pV;
						pU+=4;
						pV+=4;
					}
					_YUVtoBGR(img.at<Vec3b>(y, x), yuv);
				}
			}
		}
		break;
	case YUV_444:
		{
			PBYTE pY = pYUV;
			PBYTE pU = pYUV + w*h;
			PBYTE pV = pYUV + w*h*2;
			for (int y = 0;y < h;y++)
			{
				for (int x = 0;x < w;x++)
				{
					yuv[0] = *pY++;
					yuv[1] = *pU++;
					yuv[2] = *pV++;
					_YUVtoBGR(img.at<Vec3b>(y, x), yuv);
				}
			}
		}
		break;
	}

}

void ImageBGR2YUV(Mat& img, PBYTE pYUV, int type)
{
	CFunctionLog fl(__FUNCTION__);
	int w = img.cols;
	int h = img.rows;
	w = ALIGN_DOWN(w, 4);
	h = ALIGN_DOWN(h, 4);
	Vec3b yuv;
	switch(type)
	{

	case YUV_NV21:
	case YUV_NV12:
		{
			PBYTE pUV = pYUV+w*h;
			PBYTE pY = pYUV;
			int vidx = type == YUV_NV12 ? 1 : 2;
			int uidx = type == YUV_NV12 ? 2 : 1;
			for (int y = 0;y < h;y++)
			{
				for (int x = 0;x < w;x++)
				{
					Vec3b c = img.at<Vec3b>(y, x);
					_BGRtoYUV(c, yuv);
					*pY++ = yuv[0];
					if(y%2==0&&x%2==0) {
						pUV[y/2*w+x/2*2] = yuv[uidx];
						pUV[y/2*w+x/2*2+1] = yuv[vidx];
					}
				}
			}
		}
		break;
	case YUV_I420:
	case YUV_YV12:
		{
			PBYTE pY = pYUV;
			PBYTE pV = pYUV+w*h*5/4;
			PBYTE pU = pYUV+w*h;
			int uidx = type == YUV_I420 ? 1 : 2;
			int vidx = type == YUV_I420 ? 2 : 1;
			for (int y = 0;y < h;y++)
			{
				for (int x = 0;x < w;x++)
				{
					Vec3b c = img.at<Vec3b>(y, x);
					_BGRtoYUV(c, yuv);
					*pY++ = yuv[0];
					if(y%2==0&&x%2==0) {
						*pU++ = yuv[uidx];
						*pV++ = yuv[vidx];
					}
				}
			}
		}
		break;
	case YUV_YUYV:
	case YUV_UYVY:
		{
			int yidx = type == YUV_YUYV ? 0 : 1;
			int uidx = type == YUV_YUYV ? 1 : 0;
			int vidx = type == YUV_YUYV ? 3 : 2;
			PBYTE pY = pYUV + yidx;
			PBYTE pV = pYUV + vidx;
			PBYTE pU = pYUV + uidx;

			for (int y = 0;y < h;y++)
			{
				for (int x = 0;x < w;x++)
				{
					Vec3b c = img.at<Vec3b>(y, x);
					_BGRtoYUV(c, yuv);
					*pY = yuv[0];
					pY+=2;
					if(x%2==0) {
						*pU = yuv[1];
						*pV = yuv[2];           
						pU+=4;
						pV+=4;
					}

				}
			}
		}
		break;
	case YUV_444:
		{
			PBYTE pY = pYUV;
			PBYTE pU = pYUV + w*h;
			PBYTE pV = pYUV + w*h*2;

			for (int y = 0;y < h;y++)
			{
				for (int x = 0;x < w;x++)
				{
					Vec3b c = img.at<Vec3b>(y, x);
					_BGRtoYUV(c, yuv);
					*pY++ = yuv[0];
					*pU++ = yuv[1];
					*pV++ = yuv[2];
				}
			}
		}
		break;  
	}
}








还是先来张原图:


void Light(Mat& img, long brightness, long contrast)
{
	float c=(100 + contrast)/100.0f;
	brightness+=128;

	int dim(256);  
	Mat lut(1,&dim,CV_8U);  

	for(int i = 0; i < 256; i++)  
	{  
		lut.at<uchar>(i) = saturate_cast<uchar>((i-128)*c + brightness + 0.5f);
	}  

	LUT(img, lut, img);
	return;
}





void Saturation(Mat& img, int sat)
{
	uchar tableUV[256];
	float c=(100 + sat)/100.0f;
	for(int i = 0; i < 256; i++)
	{
		tableUV[i] = saturate_cast<uchar>((i-128)*c + 128.5f);
	}
	int w = img.cols;
	int h = img.rows;
	int size = GetYUVSize(w, h, YUV_NV12);
	uchar *pBuffer = new uchar[size];
	ImageBGR2YUV(img, pBuffer, YUV_NV12);
	int temp;
	for(int i = w*h; i < size; i++)
	{
		temp = pBuffer[i];
		pBuffer[i] = tableUV[temp];
		
	}
	
	ImageYUV2BGR(img, pBuffer, YUV_NV12);
	delete pBuffer;
}



void Hue(Mat& img, int h)
{
	cvtColor(img, img, CV_BGR2HLS);
	for(int x = 0; x < img.cols; x++)
	{
		for(int y = 0; y < img.rows; y++)
		{
			Vec3b c = img.at<Vec3b>(y, x);
			c[0] = (c[0]+h)%256;
			img.at<Vec3b>(y, x) = c;
		}
	}
	cvtColor(img, img, CV_HLS2BGR);
}



        case ID_COLOR_NEGATIVE:
		dst= Scalar(255, 255, 255) - image;
		break;
	case ID_COLOR_GRAYSCALE:
		cvtColor(image, dst, CV_BGR2GRAY);
		cvtColor(dst, dst, CV_GRAY2BGR);
		break;
	case ID_COLOR_THRESHOLD:
		cvtColor(image, dst, CV_BGR2GRAY);
		threshold(dst, dst, 100, 255, CV_THRESH_OTSU | CV_THRESH_BINARY_INV);
		cvtColor(dst, dst, CV_GRAY2BGR);



源码已公开,大家可以一起来完善这个工具。有好的想法也可以Email: 2723367319@qq.com

http://download.csdn.net/detail/fallingstar08/5747747


原文地址:https://www.cnblogs.com/dyllove98/p/3188363.html