Exemple #1
0
void DiffuseGain::applyPtmRGB(const PyramidCoeff& redCoeff, const PyramidCoeff& greenCoeff, const PyramidCoeff& blueCoeff, const QSize* mipMapSize, const PyramidNormals& normals, const RenderingInfo& info, unsigned char* buffer)
{
	int offsetBuf = 0;
	const PTMCoefficient* redPtr = redCoeff.getLevel(info.level);
	const PTMCoefficient* greenPtr = greenCoeff.getLevel(info.level);
	const PTMCoefficient* bluePtr = blueCoeff.getLevel(info.level);
	const vcg::Point3f* normalsPtr = normals.getLevel(info.level);
	// Creates the output texture.
	
    #pragma omp parallel for schedule(static,CHUNK)
	for (int y = info.offy; y < info.offy + info.height; y++)
	{
        int offsetBuf = ((y-info.offy)*info.width)<<2;
		int offset = y * mipMapSize[info.level].width() + info.offx;
		for (int x = info.offx; x < info.offx + info.width; x++)
		{
			buffer[offsetBuf + 0] = tobyte(applyModel(&(redPtr[offset][0]), normalsPtr[offset].X(), normalsPtr[offset].Y(), info.light.X(), info.light.Y()));
			buffer[offsetBuf + 1] = tobyte(applyModel(&(greenPtr[offset][0]), normalsPtr[offset].X(), normalsPtr[offset].Y(), info.light.X(), info.light.Y()));
			buffer[offsetBuf + 2] = tobyte(applyModel(&(bluePtr[offset][0]), normalsPtr[offset].X(), normalsPtr[offset].Y(), info.light.X(), info.light.Y()));
            buffer[offsetBuf + 3] = 255;
			offset++;
			offsetBuf += 4;
		}
	}
	//qDebug() << "gain = " << DiffuseGain::gain;
}
Exemple #2
0
void CoeffEnhancement::applyPtmRGB(const PyramidCoeff& redCoeff, const PyramidCoeff& greenCoeff, const PyramidCoeff& blueCoeff, const QSize* mipMapSize, const PyramidNormals& normals, const RenderingInfo& info, unsigned char* buffer)
{
	//int offsetBuf = 0;
	const PTMCoefficient* redPtr = redCoeff.getLevel(info.level);
	const PTMCoefficient* greenPtr = greenCoeff.getLevel(info.level);
	const PTMCoefficient* bluePtr = blueCoeff.getLevel(info.level);
	int lenght = info.width * info.height;
	PTMCoefficient* redC = new PTMCoefficient[lenght];
	PTMCoefficient* greenC = new PTMCoefficient[lenght];
	PTMCoefficient* blueC = new PTMCoefficient[lenght];
	int width = mipMapSize[info.level].width();
	// Creates the map of the coefficients of the sub-image in the current view of the browser
	#pragma omp parallel for schedule(static,CHUNK)
	for (int y = info.offy; y < info.offy + info.height; y++)
	{
		int offset = y * width + info.offx;
		int offset2 = (y - info.offy)*info.width;
		for (int x = info.offx; x < info.offx + info.width; x++)
		{
			memcpy(&redC[offset2], &redPtr[offset], sizeof(PTMCoefficient));
			memcpy(&greenC[offset2], &greenPtr[offset], sizeof(PTMCoefficient));
			memcpy(&blueC[offset2], &bluePtr[offset], sizeof(PTMCoefficient));
			offset++;
			offset2++;
		}
	}
	// Computes the enhanced coefficients
	enhancedCoeff(redC, info.width, info.height, 6);
	enhancedCoeff(greenC, info.width, info.height, 6);
	enhancedCoeff(blueC, info.width, info.height, 6);
	// Creates the output texture.	
	LightMemoized lVec(info.light.X(), info.light.Y());
	
	#pragma omp parallel for schedule(static,CHUNK)
	for (int y = info.offy; y < info.offy + info.height; y++)
	{
		int offsetBuf = (y-info.offy)*info.width*4;
		int offset2 = (y - info.offy)*info.width;
		for (int x = info.offx; x < info.offx + info.width; x++)
		{
			buffer[offsetBuf] = tobyte(redC[offset2].evalPoly(lVec)); 
			buffer[offsetBuf + 1] = tobyte(greenC[offset2].evalPoly(lVec));
			buffer[offsetBuf + 2] = tobyte(blueC[offset2].evalPoly(lVec));
			buffer[offsetBuf + 3] = 255;
			offsetBuf += 4;
			offset2++;
		}
	}
	delete[] redC;
	delete[] greenC;
	delete[] blueC;
}
Exemple #3
0
void DiffuseGain::applyPtmLRGB(const PyramidCoeff& coeff, const PyramidRGB& rgb, const QSize* mipMapSize, const PyramidNormals& normals, const RenderingInfo& info, unsigned char* buffer)
{
	int offsetBuf = 0;
	const unsigned char* rgbPtr = rgb.getLevel(info.level);
	const PTMCoefficient* coeffPtr = coeff.getLevel(info.level);
	const vcg::Point3f* normalsPtr = normals.getLevel(info.level);
	// Creates the output texture.

    #pragma omp parallel for schedule(static,CHUNK)
	for (int y = info.offy; y < info.offy + info.height; y++)
	{
        int offsetBuf = ((y-info.offy)*info.width)<<2;
		int offset = y * mipMapSize[info.level].width() + info.offx;
		for (int x = info.offx; x < info.offx + info.width; x++)
		{
			//int offset = y * mipMapSize[info.level].width() + x;
            float lum = applyModel(&(coeffPtr[offset][0]), normalsPtr[offset].X(), normalsPtr[offset].Y(), info.light.X(), info.light.Y()) / 256.0f;
			int offset3 = offset*3;
			for (int i = 0; i < 3; i++)
				buffer[offsetBuf + i] = tobyte(rgbPtr[offset3 + i] * lum);
            buffer[offsetBuf + 3] = 255;
			offsetBuf += 4;
			offset++;
		}
	}
	//qDebug() << "gain = " << DiffuseGain::gain;
}
Exemple #4
0
void SpecularEnhancement::applyPtmRGB(const PyramidCoeff& redCoeff, const PyramidCoeff& greenCoeff, const PyramidCoeff& blueCoeff, const QSize* mipMapSize, const PyramidNormals& normals, const RenderingInfo& info, unsigned char* buffer)
{
	// Creates the output texture.
	const PTMCoefficient* redPtr = redCoeff.getLevel(info.level);
	const PTMCoefficient* greenPtr = greenCoeff.getLevel(info.level);
	const PTMCoefficient* bluePtr = blueCoeff.getLevel(info.level);
	const vcg::Point3f* normalsPtr = normals.getLevel(info.level);
	LightMemoized lVec(info.light.X(), info.light.Y());
	
	#pragma omp parallel for schedule(static,CHUNK)
	for (int y = info.offy; y < info.offy + info.height; y++)
	{
		int offsetBuf = (y-info.offy)*info.width<<2;
		int offset = y * mipMapSize[info.level].width() + info.offx;
		for (int x = info.offx; x < info.offx + info.width; x++)
		{
			vcg::Point3f h(0, 0, 1);
			h += info.light;
			h /= 2;
			h.Normalize();
            float nDotH = h * normalsPtr[offset];
			if (nDotH < 0) 
				nDotH = 0.0;
			else if (nDotH > 1)
				nDotH = 1.0;
			nDotH = pow(nDotH, exp);
			float r = redPtr[offset].evalPoly(lVec);
			float g = greenPtr[offset].evalPoly(lVec);
            float b = bluePtr[offset].evalPoly(lVec);
			float temp = (r + g + b)/3;
            float lum =  temp * ks * 2 * nDotH;
			buffer[offsetBuf + 0] = tobyte( r * kd + lum);
			buffer[offsetBuf + 1] = tobyte( g * kd + lum );
			buffer[offsetBuf + 2] = tobyte( b * kd + lum );
			buffer[offsetBuf + 3] = 255;
			offsetBuf += 4;
			offset++;
		}
	}
}
Exemple #5
0
QImage* RGBPtm::createPreview(int width, int height)
{
	// Computes the height and the width of the preview.
	int level = 3;
	int imageH = mipMapSize[3].height();
	int imageW = mipMapSize[3].width();
	for (int i = 0; i < 4; i++)
	{
		if (mipMapSize[i].width() <= width || mipMapSize[i].height() <= height)
		{
			if (mipMapSize[i].width() < width && mipMapSize[i].height() < height && i > 0)
				i--;
			imageH = mipMapSize[i].height();
			imageW = mipMapSize[i].width();
			level = i;
			break;
		}
	}
	
	// Creates the preview.
	unsigned char* buffer = new unsigned char[imageH*imageW*4];
	const PTMCoefficient* redPtr = redCoefficients.getLevel(level);
	const PTMCoefficient* greenPtr = greenCoefficients.getLevel(level);
	const PTMCoefficient* bluePtr = blueCoefficients.getLevel(level);
	int offset = 0;
	for (int i = 0; i < imageH; i++)
	{
		for (int j = 0; j < imageW; j++)
		{
			offset = i * imageW + j;
			buffer[offset*4 + 2] = tobyte(evalPoly((int*)&(redPtr[offset][0]), 0, 0));
			buffer[offset*4 + 1] = tobyte(evalPoly((int*)&(greenPtr[offset][0]), 0, 0));
			buffer[offset*4 + 0] = tobyte(evalPoly((int*)&(bluePtr[offset][0]), 0, 0));
			buffer[offset*4 + 3] = 255;
		}
	}
	QImage* image = new QImage(buffer, imageW, imageH, QImage::Format_RGB32);
	return image;
}
Exemple #6
0
void CoeffEnhancement::applyPtmLRGB(const PyramidCoeff& coeff, const PyramidRGB& rgb, const QSize* mipMapSize, const PyramidNormals& normals, const RenderingInfo& info, unsigned char* buffer)
{
	//int offsetBuf = 0;
	const PTMCoefficient* coeffPtr = coeff.getLevel(info.level);
	const unsigned char* rgbPtr = rgb.getLevel(info.level);
	PTMCoefficient* coeffMap = new PTMCoefficient[info.width*info.height];
	int width = mipMapSize[info.level].width();
	// Creates the map of the coefficients of the sub-image in the current view of the browser
	#pragma omp parallel for schedule(static,CHUNK)
	for (int y = info.offy; y < info.offy + info.height; y++)
	{
		int offset = y * width + info.offx;
		int offset2 = (y - info.offy)*info.width;
		for (int x = info.offx; x < info.offx + info.width; x++)
		{
			memcpy(coeffMap[offset2], coeffPtr[offset], sizeof(PTMCoefficient));
			offset++;
			offset2++;
		}
	}
	// Computes the enhanced coefficients.
	enhancedCoeff(coeffMap, info.width, info.height, 6);
	// Creates the output texture.
	LightMemoized lVec(info.light.X(), info.light.Y());
	
	#pragma omp parallel for schedule(static,CHUNK)
	for (int y = info.offy; y < info.offy + info.height; y++)
	{
                int offsetLoc = (y-info.offy)*info.width;
                int offsetBuf = offsetLoc << 2;
		int offset = y * width + info.offx;
		for (int x = info.offx; x < info.offx + info.width; x++)
		{
                        float lum = coeffMap[offsetLoc].evalPoly(lVec) / 255.0f;
			int offset3 = offset * 3;
			for (int i = 0; i < 3; i++)
				buffer[offsetBuf + i] = tobyte(rgbPtr[offset3 + i] * lum);
			buffer[offsetBuf + 3] = 255;
			offsetBuf +=4;
                        offset++;
                        offsetLoc++;
		}
	}
	delete[] coeffMap;
}
Exemple #7
0
void SpecularEnhancement::applyPtmLRGB(const PyramidCoeff& coeff, const PyramidRGB& rgb, const QSize* mipMapSize, const PyramidNormals& normals, const RenderingInfo& info, unsigned char* buffer)
{
	// Creates the output texture.
	//int offsetBuf = 0;
	const PTMCoefficient* coeffPtr = coeff.getLevel(info.level);
	const unsigned char* rgbPtr = rgb.getLevel(info.level);
	const vcg::Point3f* normalsPtr = normals.getLevel(info.level);
	LightMemoized lVec(info.light.X(), info.light.Y());
	
	#pragma omp parallel for schedule(static,CHUNK) 
	for (int y = info.offy; y < info.offy + info.height; y++)
	{
		int offsetBuf = (y-info.offy)*info.width*4;
		int offset = y * mipMapSize[info.level].width() + info.offx;
		for (int x = info.offx; x < info.offx + info.width; x++)
		{
			float lum = coeffPtr[offset].evalPoly(lVec) / 255.0f;
            vcg::Point3f h(0, 0, 1);
			h += info.light;
			h /= 2;
			h.Normalize();
			float nDotH = h * normalsPtr[offset];
			if (nDotH < 0) 
				nDotH = 0.0;
			else if (nDotH > 1)
				nDotH = 1.0;
			nDotH = pow(nDotH, exp);
			nDotH *= ks*255;
			int offset3 = offset*3;
			for (int i = 0; i < 3; i++)
				buffer[offsetBuf + i]  = tobyte((rgbPtr[offset3 + i]*kd + nDotH)*lum);
			buffer[offsetBuf + 3] = 255;
			offsetBuf += 4;
			offset++;
		}
	}

}
void UnsharpMasking::applyPtmRGB(const PyramidCoeff& redCoeff, const PyramidCoeff& greenCoeff, const PyramidCoeff& blueCoeff, const QSize* mipMapSize, const PyramidNormals& normals, const RenderingInfo& info, unsigned char* buffer)
{
	int offsetBuf = 0;
	const PTMCoefficient* redPtr = redCoeff.getLevel(info.level);
	const PTMCoefficient* greenPtr = greenCoeff.getLevel(info.level);
	const PTMCoefficient* bluePtr = blueCoeff.getLevel(info.level);
	const vcg::Point3f* normalsPtr = normals.getLevel(info.level);
    float* lumMap = new float[info.width*info.height];
	int width = mipMapSize[info.level].width();
	if (type == 0) //classic unsharp masking
	{
        float* uvMap = new float[info.width*info.height*2];
		LightMemoized lVec(info.light.X(), info.light.Y());
        
		#pragma omp parallel for schedule(static,CHUNK)
		for (int y = info.offy; y < info.offy + info.height; y++)
		{
            int offsetBuf = (y-info.offy)*info.width<<2;
			int offset = y * width + info.offx;
			int offset2 = (y - info.offy)*info.width;
			for (int x = info.offx; x < info.offx + info.width; x++)
			{
				float r = redPtr[offset].evalPoly(lVec) / 255.0;//evalPoly((int*)&(redPtr[offset][0]), info.light.X(), info.light.Y()) / 255.0;
                float g = greenPtr[offset].evalPoly(lVec) / 255.0;//evalPoly((int*)&(greenPtr[offset][0]), info.light.X(), info.light.Y()) / 255.0;
                float b = bluePtr[offset].evalPoly(lVec) / 255.0;//evalPoly((int*)&(bluePtr[offset][0]), info.light.X(), info.light.Y()) / 255.0;
				getYUV(r, g, b, lumMap[offset2], uvMap[offset2*2], uvMap[offset2*2 + 1]);
				offset++;
				offset2++;
			}
		}
		enhancedLuminance(lumMap, info.width, info.height, info.mode);
		bool flag = (info.mode == LUM_UNSHARP_MODE || info.mode == SMOOTH_MODE || info.mode == CONTRAST_MODE || info.mode == ENHANCED_MODE);
		if (flag)
		{
			#pragma omp parallel for schedule(static,CHUNK)
			for (int y = info.offy; y < info.offy + info.height; y++)
			{
				int offsetBuf = (y-info.offy)*info.width<<2;
				int offset2 =(y - info.offy)*info.width; 
				for (int x = info.offx; x < info.offx + info.width; x++)
				{
					for (int i = 0; i < 3; i++)
						buffer[offsetBuf + i] = tobyte(lumMap[offset2] * 255.0);
					buffer[offsetBuf + 3] = 255;
					offsetBuf += 4;
					offset2++;
				}
			}
		}
		else
		{
			#pragma omp parallel for schedule(static,CHUNK)
			for (int y = info.offy; y < info.offy + info.height; y++)
			{
				int offsetBuf = (y-info.offy)*info.width<<2;
				int offset2 =(y - info.offy)*info.width; 
				for (int x = info.offx; x < info.offx + info.width; x++)
				{
					float r, g, b;
					getRGB(lumMap[offset2], uvMap[offset2*2], uvMap[offset2*2 +1], r, g, b);
					buffer[offsetBuf] = tobyte(r*255);
					buffer[offsetBuf + 1] = tobyte(g*255);
					buffer[offsetBuf + 2] = tobyte(b*255);
					buffer[offsetBuf + 3] = 255;
					offsetBuf += 4;
					offset2++;
				}
			}
		}
		delete[] uvMap;
	}
	else //luminance unsharp masking
	{
        #pragma omp parallel for schedule(static,CHUNK)
		for (int y = info.offy; y < info.offy + info.height; y++)
		{
			int offset= y * width + info.offx;
			int offset2 = (y - info.offy)*info.width;
			for (int x = info.offx; x < info.offx + info.width; x++)
			{
				lumMap[offset2] = getLum(normalsPtr[offset], info.light);
				offset++;
				offset2++;
			}
		}
		enhancedLuminance(lumMap, info.width, info.height, info.mode);
		bool flag = (info.mode == LUM_UNSHARP_MODE || info.mode == SMOOTH_MODE || info.mode == CONTRAST_MODE || info.mode == ENHANCED_MODE);
		LightMemoized lVec(info.light.X(), info.light.Y());
		if (flag)
		{
			#pragma omp parallel for schedule(static,CHUNK)
			for (int y = info.offy; y < info.offy + info.height; y++)
			{
				int offsetBuf = (y-info.offy)*info.width<<2;
				int offset = y * width + info.offx;
				int offset2 = (y - info.offy)*info.width;
				for (int x = info.offx; x < info.offx + info.width; x++)
				{
					float lum = lumMap[offset2];
					for (int i = 0; i < 3; i++)
						buffer[offsetBuf + i] = tobyte(lum / 2.0 * 255.0);
					buffer[offsetBuf + 3] = 255;
					offsetBuf += 4;
					offset++;
					offset2++;
				}
			}
		}
		else
		{
			#pragma omp parallel for schedule(static,CHUNK)
			for (int y = info.offy; y < info.offy + info.height; y++)
			{
				int offsetBuf = (y-info.offy)*info.width<<2;
				int offset = y * width + info.offx;
				int offset2 = (y - info.offy)*info.width;
				for (int x = info.offx; x < info.offx + info.width; x++)
				{
					float lum = lumMap[offset2];
					buffer[offsetBuf] = tobyte(redPtr[offset].evalPoly(lVec)*lum);//evalPoly((int*)&(redPtr[offset][0]), info.light.X(), info.light.Y()) * lum);
					buffer[offsetBuf + 1] = tobyte(greenPtr[offset].evalPoly(lVec)*lum);//evalPoly((int*)&(greenPtr[offset][0]), info.light.X(), info.light.Y()) * lum);
					buffer[offsetBuf + 2] = tobyte(bluePtr[offset].evalPoly(lVec)*lum);//evalPoly((int*)&(bluePtr[offset][0]), info.light.X(), info.light.Y()) * lum);
					buffer[offsetBuf + 3] = 255;
					offsetBuf += 4;
					offset++;
					offset2++;
				}
			}
		}
	}
	delete[] lumMap;
}
void UnsharpMasking::applyPtmLRGB(const PyramidCoeff& coeff, const PyramidRGB& rgb, const QSize* mipMapSize, const PyramidNormals& normals, const RenderingInfo& info, unsigned char* buffer)
{
	int offsetBuf = 0;
	const PTMCoefficient* coeffPtr = coeff.getLevel(info.level);
	const unsigned char* rgbPtr = rgb.getLevel(info.level);
    float* lumMap = new float[info.width*info.height];
	int width = mipMapSize[info.level].width();
	if (type == 0) //image unsharp masking
	{
		// Creates a map for Y component and a map for UV component. 
        float* uvMap = new float[info.width*info.height*2];
		LightMemoized lVec(info.light.X(), info.light.Y());
        
		#pragma omp parallel for schedule(static,CHUNK)
		for (int y = info.offy; y < info.offy + info.height; y++)
		{
            int offsetBuf = (y-info.offy)*info.width<<2;
			int offset = (y * width + info.offx)*3;
			int offset2 = ((y - info.offy)*info.width)*2;
			for (int x = info.offx; x < info.offx + info.width; x++)
			{
			    float lum =  coeffPtr[offset / 3].evalPoly(lVec) / 255.0;
                float r = rgbPtr[offset]*lum / 255.0;
                float g = rgbPtr[offset + 1]*lum / 255.0;
                float b = rgbPtr[offset + 2]*lum / 255.0;
				getYUV(r, g, b, lumMap[offset2 / 2], uvMap[offset2], uvMap[offset2 + 1]);
				offset += 3;
				offset2 += 2;
			}
		}
		// Computes the enhanced luminance.
		enhancedLuminance(lumMap, info.width, info.height, info.mode);
		// Creates the output texture.
		bool flag = (info.mode == LUM_UNSHARP_MODE || info.mode == SMOOTH_MODE || info.mode == CONTRAST_MODE ||info.mode == ENHANCED_MODE);
		if (flag)
		{
			#pragma omp parallel for schedule(static,CHUNK)
			for (int y = info.offy; y < info.offy + info.height; y++)
			{
				int offsetBuf = (y - info.offy) * info.width << 2;
				int offset2 =(y - info.offy) * info.width;
				for (int x = info.offx; x < info.offx + info.width; x++)
				{
					for (int i = 0; i < 3; i++)
						buffer[offsetBuf + i] = tobyte(lumMap[offset2] * 255.0);
					buffer[offsetBuf + 3] = 255;
					offsetBuf += 4;
					offset2++;
				}
			}
		}
		else
		{
			#pragma omp parallel for schedule(static,CHUNK)
			for (int y = info.offy; y < info.offy + info.height; y++)
			{
				int offsetBuf = (y - info.offy) * info.width << 2;
				int offset2 =(y - info.offy)*info.width * 2;
				for (int x = info.offx; x < info.offx + info.width; x++)
				{
					float r, g, b;
					getRGB(lumMap[offset2 / 2], uvMap[offset2], uvMap[offset2 + 1], r, g, b);
					buffer[offsetBuf ] = tobyte(r*255);
					buffer[offsetBuf + 1] = tobyte(g*255);
					buffer[offsetBuf + 2] = tobyte(b*255);
					buffer[offsetBuf + 3] = 255;
					offsetBuf += 4;
					offset2 += 2;
				}
			}
		}
		delete[] uvMap;
	}
	else //unsharp masking luminance
	{
		// Creates a map for the polynomial luminance.
		LightMemoized lVec(info.light.X(), info.light.Y());
		
		#pragma omp parallel for schedule(static,CHUNK)
		for (int y = info.offy; y < info.offy + info.height; y++)
		{
			int offset = y * width + info.offx;
			int offset2 = (y - info.offy)*info.width;
			for (int x = info.offx; x < info.offx + info.width; x++)
			{
				lumMap[offset2] = coeffPtr[offset].evalPoly(lVec) / 255.0;
				offset++;
				offset2++;
			}
		}
		// Computes the enhanced luminance
		enhancedLuminance(lumMap, info.width, info.height, info.mode);
		// Creates the output texture.
		bool flag = (info.mode == LUM_UNSHARP_MODE || info.mode == SMOOTH_MODE || info.mode == CONTRAST_MODE || info.mode == ENHANCED_MODE);
        if (flag)
		{
			#pragma omp parallel for schedule(static,CHUNK)
			for (int y = info.offy; y < info.offy + info.height; y++)
			{
				int offsetBuf = (y - info.offy) * info.width <<2;
				int offset2 = (y - info.offy) * info.width;
				for (int x = info.offx; x < info.offx + info.width; x++)
				{
					for (int i = 0; i < 3; i++)
						buffer[offsetBuf + i] = tobyte(lumMap[offset2] / 2.0 * 255.0);
					buffer[offsetBuf + 3] = 255;
					offsetBuf += 4;
					offset2++;
				}
			}
		}
		else
		{
			#pragma omp parallel for schedule(static,CHUNK)
			for (int y = info.offy; y < info.offy + info.height; y++)
			{
				int offsetBuf = (y - info.offy) * info.width << 2;
				int offset = (y * width + info.offx)*3;
				int offset2 = (y - info.offy) * info.width; 
				for (int x = info.offx; x < info.offx + info.width; x++)
				{
					for (int i = 0; i < 3; i++)
						buffer[offsetBuf + i] = tobyte(rgbPtr[offset + i] * lumMap[offset2]);
					buffer[offsetBuf + 3] = 255;
					offsetBuf += 4;
					offset += 3;
					offset2++;
				}
			}

		}
		
	}
	delete[] lumMap;
}
Exemple #10
0
static void nonmax_suppress (float **dx, float **dy, imImage* mag)
{
  int i,j;
  float xx, yy, g2, g1, g3, g4, g, xc, yc;
  unsigned char* mag_data = (unsigned char*)mag->data[0];

  for (i=1; i<mag->height-1; i++)
  {
    for (j=1; j<mag->width-1; j++)
    {
      /* Treat the x and y derivatives as components of a vector */
      xc = dx[i][j];
      yc = dy[i][j];
      if (fabs(xc)<0.01 && fabs(yc)<0.01) continue;

      g  = norm (xc, yc);

      /* Follow the gradient direction, as indicated by the direction of
        the vector (xc, yc); retain pixels that are a local maximum. */

      if (fabs(yc) > fabs(xc))
      {
        /* The Y component is biggest, so gradient direction is basically UP/DOWN */
        xx = (float)(fabs(xc)/fabs(yc));
        yy = 1.0;

        g2 = norm (dx[i-1][j], dy[i-1][j]);
        g4 = norm (dx[i+1][j], dy[i+1][j]);
        if (xc*yc > 0.0)
        {
          g3 = norm (dx[i+1][j+1], dy[i+1][j+1]);
          g1 = norm (dx[i-1][j-1], dy[i-1][j-1]);
        } 
        else
        {
          g3 = norm (dx[i+1][j-1], dy[i+1][j-1]);
          g1 = norm (dx[i-1][j+1], dy[i-1][j+1]);
        }

      } 
      else
      {
        /* The X component is biggest, so gradient direction is basically LEFT/RIGHT */
        xx = (float)(fabs(yc)/fabs(xc));
        yy = 1.0;

        g2 = norm (dx[i][j+1], dy[i][j+1]);
        g4 = norm (dx[i][j-1], dy[i][j-1]);
        if (xc*yc > 0.0)
        {
          g3 = norm (dx[i-1][j-1], dy[i-1][j-1]);
          g1 = norm (dx[i+1][j+1], dy[i+1][j+1]);
        }
        else
        {
          g1 = norm (dx[i-1][j+1], dy[i-1][j+1]);
          g3 = norm (dx[i+1][j-1], dy[i+1][j-1]);
        }
      }

      /* Compute the interpolated value of the gradient magnitude */
      if ( (g > (xx*g1 + (yy-xx)*g2)) && (g > (xx*g3 + (yy-xx)*g4)) )
      {
        mag_data[i*mag->width + j] = tobyte(g*MAG_SCALE);
      } 
    }
  }
}
Exemple #11
0
int RGBPtm::createImage(unsigned char** buffer, int& width, int& height, const vcg::Point3f& light, const QRectF& rect, int level, int mode)
{
#ifdef PRINT_DEBUG
	QTime first = QTime::currentTime();
#endif

	// Computes height and width of the texture.
	width = ceil(rect.width());
	height = ceil(rect.height());
	int offx = rect.x();
	int offy = rect.y();
    if (currentRendering != DETAIL_ENHANCEMENT || mode == LUMR_MODE || mode == LUMG_MODE || mode == LUMB_MODE)
    {
		for (int i = 0; i < level; i++)
		{
			width = ceil(width/2.0);
			height = ceil(height/2.0);
			offx = offx/2;
			offy = offy/2;
		}
	}

	(*buffer) = new unsigned char[width*height*4];
	int offsetBuf = 0;
	
    if (mode == LUMR_MODE || mode == LUMG_MODE || mode == LUMB_MODE)
	{
		// Creates map of the RGB component.
		const PTMCoefficient* coeffPtr = NULL;
		switch(mode)
		{
			case LUMR_MODE:
				coeffPtr = redCoefficients.getLevel(level); break;
			case LUMB_MODE:
				coeffPtr = greenCoefficients.getLevel(level); break;
			case LUMG_MODE:
				coeffPtr = blueCoefficients.getLevel(level); break;
		}
		for (int y = offy; y < offy + height; y++)
		{
			for (int x = offx; x < offx + width; x++)
			{
				int offset = y * mipMapSize[level].width() + x;
				unsigned char c = tobyte(evalPoly((int*)&(coeffPtr[offset][0]), light.X(), light.Y()));
				(*buffer)[offsetBuf + 0] = c;
				(*buffer)[offsetBuf + 1] = c;
				(*buffer)[offsetBuf + 2] = c;
				(*buffer)[offsetBuf + 3] = 255;
				offsetBuf += 4;
			}
		}

	}
	else
	{
		// Applies the current rendering mode.
		RenderingInfo info = {offx, offy, height, width, level, mode, light, 6};
		list->value(currentRendering)->applyPtmRGB(redCoefficients, greenCoefficients, blueCoefficients, mipMapSize, normals, info, (*buffer));
	}
	
#ifdef PRINT_DEBUG
	QTime second = QTime::currentTime();
	double diff = first.msecsTo(second) / 1000.0;
	if (mode == DEFAULT_MODE)
	{
		switch(currentRendering)
		{
                        case DEFAULT: printf("Default rendering: %.5f s\n", diff); break;
                        case NORMALS: printf("Normals: %.5f s\n", diff); break;
                        case DIFFUSE_GAIN: printf("Diffuse gain: %.5f s\n", diff); break;
                        case SPECULAR_ENHANCEMENT: printf("Specular enhancement: %.5f s\n", diff); break;
                        case NORMAL_ENHANCEMENT: printf("Normal enhancement: %.5f s\n", diff); break;
                        case UNSHARP_MASKING_IMG: printf("Unsharp masking image: %.5f s\n", diff); break;
                        case UNSHARP_MASKING_LUM: printf("Unsharp masking luminance: %.5f s\n", diff); break;
                        case COEFF_ENHANCEMENT: printf("Coefficient enhancement: %.5f s\n", diff); break;
                        case DETAIL_ENHANCEMENT: printf("Detail enhancement: %.5f s\n", diff); break;
                        case DYN_DETAIL_ENHANCEMENT: printf("Dynamic detail enhancement: %.5f s\n", diff); break;
		}
	}
	else
                printf("Browing mode: %.5f s\n", diff);
#endif
	return 0;
}
Exemple #12
0
void SpecularEnhancement::applyHSH(const PyramidCoeffF& redCoeff, const PyramidCoeffF& greenCoeff, const PyramidCoeffF& blueCoeff, const QSize* mipMapSize, const PyramidNormals& normals, const RenderingInfo& info, unsigned char* buffer)
{
	const float* redPtr = redCoeff.getLevel(info.level);
	const float* greenPtr = greenCoeff.getLevel(info.level);
	const float* bluePtr = blueCoeff.getLevel(info.level);
	const vcg::Point3f* normalsPtr = normals.getLevel(info.level);
	int tempW = mipMapSize[info.level].width();
    float hweights[9];
	vcg::Point3d temp(info.light.X(), info.light.Y(), info.light.Z());
	temp.Normalize();
	float phi = atan2(temp.Y(), temp.X());
	if (phi<0) 
		phi = 2*M_PI+phi;
    float theta = qMin<float>(acos(temp.Z()/temp.Norm()), M_PI / 2 - 0.04);

	//int offsetBuf = 0;
	getHSH(theta, phi, hweights, sqrt((float)info.ordlen));
	
	#pragma omp parallel for schedule(static,CHUNK) 
	for (int y = info.offy; y < info.offy + info.height; y++)
	{
		int offsetBuf = (y-info.offy)*info.width*4;
		int offset= y * tempW + info.offx;
		for (int x = info.offx; x < info.offx + info.width; x++)
		{
            float red = 0, green = 0, blue = 0;
			int offset2 = offset * info.ordlen;
			for (int k = 0; k < info.ordlen; k++)
			{
				int offset3 = offset2 + k;
				red += redPtr[offset3] * hweights[k];
				green += greenPtr[offset3] * hweights[k];
				blue += bluePtr[offset3] * hweights[k];
			}
			red *= 256;
			green *= 256;
			blue *= 256;

            vcg::Point3f h(0.0f, 0.0f, 1.0f);
			h += info.light;
            h /= 2.0f;
			h.Normalize();

            float nDotH = h * normalsPtr[offset];
			if (nDotH < 0) 
				nDotH = 0.0;
            else if (nDotH > 1.0f)
				nDotH = 1.0;
            nDotH = pow(nDotH, exp/5.0f);

            float temp = (red + green + blue)/3;
            float lum =  temp * ks * 4.0f * nDotH;
			buffer[offsetBuf + 0] = tobyte( red * kd + lum);
			buffer[offsetBuf + 1] = tobyte( green * kd + lum );
			buffer[offsetBuf + 2] = tobyte( blue * kd + lum );
            buffer[offsetBuf + 3] = 0xff;
			offsetBuf += 4;
			offset++;
		}
	}


}