333 lines
8.5 KiB
C++
333 lines
8.5 KiB
C++
#include "stdafx.h"
|
|
#include "./ImageMapping.h"
|
|
|
|
namespace ImageMapping
|
|
{
|
|
/*
|
|
* 线性调光
|
|
*/
|
|
namespace LinarMapping
|
|
{
|
|
bool CalculateKC_u(float& fK, float& fC, unsigned short* psh16BitData, int nDataLen, int nBrightness, int nContrast)
|
|
{
|
|
if (NULL == psh16BitData || nDataLen <= 0)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
//指向直方图的数据指针
|
|
int pHist[65536] = { 0 };
|
|
memset(pHist, 0, 65536 * sizeof(int));
|
|
|
|
int i = 0;
|
|
for (i = 0; i < nDataLen; i++)
|
|
{
|
|
pHist[psh16BitData[i]]++;
|
|
}
|
|
|
|
//设置阈值大小为: AreaSigma*图象大小/100
|
|
//int nSigma = (3 * nDataLen)/100; // 按比例抛点 3%
|
|
int nSigma = 3 * 768;
|
|
int nSum = 0;
|
|
int nMin = 0;
|
|
int nMax = 0;
|
|
|
|
//求映射的最大最小值
|
|
for (i = 0; i < 65536; i++)
|
|
{
|
|
nSum += pHist[i];
|
|
if (nSum >= nSigma)
|
|
{
|
|
nMin = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
nSum = 0;
|
|
for (i = 65535; i >= 0; i--)
|
|
{
|
|
nSum += pHist[i];
|
|
if (nSum >= nSigma)
|
|
{
|
|
nMax = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
nBrightness = (nBrightness > 100) ? 100 : nBrightness;
|
|
nBrightness = (nBrightness < 0) ? 0 : nBrightness;
|
|
|
|
nContrast = (nContrast > 100) ? 100 : nContrast;
|
|
nContrast = (nContrast < 0) ? 0 : nContrast;
|
|
|
|
//计算对比度亮度
|
|
fK = (float)(256.0 / (nMax - nMin + 1)) * float(nBrightness / 100.0);
|
|
fC = (float)(-fK * nMin) * float(nContrast / 100.0);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool CalculateKC(float& fK, float& fC, short* psh16BitData, int nDataLen, int nBrightness, int nContrast)
|
|
{
|
|
if (NULL == psh16BitData || nDataLen <= 0)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
//指向直方图的数据指针
|
|
int pHist[65536] = { 0 };
|
|
memset(pHist, 0, sizeof(pHist));
|
|
|
|
int i = 0;
|
|
for (i = 0; i < nDataLen; i++)
|
|
{
|
|
pHist[psh16BitData[i] + 32768]++;
|
|
}
|
|
|
|
//设置阈值大小为: AreaSigma*图象大小/100
|
|
//int nSigma = (3 * nDataLen)/100; // 按比例抛点 3%
|
|
int nSigma = 3 * 768;
|
|
int nSum = 0;
|
|
int nMin = 0;
|
|
int nMax = 0;
|
|
|
|
//求映射的最大最小值
|
|
for (i = 0; i < 65536; i++)
|
|
{
|
|
nSum += pHist[i];
|
|
if (nSum >= nSigma)
|
|
{
|
|
nMin = i - 32768;
|
|
break;
|
|
}
|
|
}
|
|
|
|
nSum = 0;
|
|
for (i = 65535; i >= 0; i--)
|
|
{
|
|
nSum += pHist[i];
|
|
if (nSum >= nSigma)
|
|
{
|
|
nMax = i - 32768;
|
|
break;
|
|
}
|
|
}
|
|
|
|
nBrightness = (nBrightness > 100) ? 100 : nBrightness;
|
|
nBrightness = (nBrightness < 0) ? 0 : nBrightness;
|
|
|
|
nContrast = (nContrast > 100) ? 100 : nContrast;
|
|
nContrast = (nContrast < 0) ? 0 : nContrast;
|
|
|
|
//计算对比度亮度
|
|
fK = (float)(256.0 / (nMax - nMin + 1)) * float(nBrightness / 100.0);
|
|
fC = (float)(-fK * nMin) * float(nContrast / 100.0);
|
|
|
|
return true;
|
|
}
|
|
|
|
/*
|
|
* 将Y16数据转换成Y8数据
|
|
*/
|
|
bool Map16BitTo8Bit_u(unsigned short* psh16BitData, int nDataLen, unsigned char* pby8BitData, float fK, float fC)
|
|
{
|
|
if (nullptr == psh16BitData || nullptr == pby8BitData || nDataLen <= 0)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
__m256i varMi_Value = _mm256_set_epi32(0, 0, 0, 0, 0, 0, 0, 0);
|
|
__m256 varM_Value = _mm256_set_ps(0, 0, 0, 0, 0, 0, 0, 0);
|
|
|
|
__m256 varM_C = _mm256_set_ps(1, 3, 1, 3, 1, 3, 1, 3);
|
|
__m256 varM_K = _mm256_set_ps(2, 2, 2, 2, 2, 2, 2, 2);
|
|
|
|
/*
|
|
#define _CMP_EQ_OQ 0x00 * Equal (ordered, nonsignaling) *
|
|
#define _CMP_LT_OS 0x01 * Less-than (ordered, signaling)
|
|
#define _CMP_LE_OS 0x02 * Less-than-or-equal (ordered, signaling) *
|
|
#define _CMP_UNORD_Q 0x03 * Unordered (nonsignaling) *
|
|
#define _CMP_NEQ_UQ 0x04 * Not-equal (unordered, nonsignaling)
|
|
#define _CMP_NLT_US 0x05 * Not-less-than (unordered, signaling)
|
|
#define _CMP_NLE_US 0x06 * Not-less-than-or-equal (unordered,signaling) *
|
|
*/
|
|
|
|
__m256 varMi_0xFF_ps1 = _mm256_cmp_ps(varM_K, varM_C, _CMP_GE_OS);
|
|
__m256i varM_Value1 = _mm256_cvtps_epi32(varMi_0xFF_ps1);
|
|
|
|
__m256i varMi_0x00 = _mm256_set_epi32(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
|
|
__m256i varMi_0xFF = _mm256_set_epi32(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF);
|
|
|
|
for (int i = 0; i < nDataLen / 8; i++)
|
|
{
|
|
/*
|
|
_mm256_set_epi32();
|
|
_mm256_cvtepi32_ps();
|
|
_mm256_mul_ps();
|
|
_mm256_add_ps();
|
|
_mm256_cvtps_epi32();
|
|
_mm256_cmpeq_epi32();
|
|
_mm256_cmpgt_epi32();
|
|
_mm256_and_si256();
|
|
_mm256_or_si256();
|
|
*/
|
|
|
|
// 计算初值
|
|
varMi_Value = _mm256_set_epi32(
|
|
psh16BitData[8 * i + 0],
|
|
psh16BitData[8 * i + 1],
|
|
psh16BitData[8 * i + 2],
|
|
psh16BitData[8 * i + 3],
|
|
psh16BitData[8 * i + 4],
|
|
psh16BitData[8 * i + 5],
|
|
psh16BitData[8 * i + 6],
|
|
psh16BitData[8 * i + 7]);
|
|
varM_Value = _mm256_cvtepi32_ps(varMi_Value);
|
|
|
|
varM_Value = _mm256_mul_ps(varM_Value, varM_K);
|
|
varM_Value = _mm256_add_ps(varM_Value, varM_C);
|
|
|
|
// float转换为int
|
|
varMi_Value = _mm256_cvtps_epi32(varM_Value);
|
|
|
|
// 计算值合规化
|
|
__m256 varMi_0xFF_ps = _mm256_cmp_ps(varM_C, varM_K, _CMP_LT_OS);
|
|
__m256i varMi_Mask_LT_0xFF = _mm256_cvtps_epi32(varMi_0xFF_ps);
|
|
//__m256i varMi_Mask_LT_0xFF = _mm_cmplt_epi32(varMi_Value, varMi_0xFF);
|
|
__m256i varMi_Mask_GT_0x00 = _mm256_cmpgt_epi32(varMi_Value, varMi_0x00);
|
|
__m256i varMi_Mask_Normal = _mm256_and_si256(varMi_Mask_LT_0xFF, varMi_Mask_GT_0x00);
|
|
__m256i varMi_Value_Normal = _mm256_and_si256(varMi_Value, varMi_Mask_Normal);
|
|
|
|
__m256i varMi_Mask_0xFF = _mm256_cmpgt_epi32(varMi_Value, varMi_0xFF);
|
|
__m256i varMi_0xFF_Valid = _mm256_and_si256(varMi_0xFF, varMi_Mask_0xFF);
|
|
|
|
varMi_Value = _mm256_or_si256(varMi_Mask_Normal, varMi_0xFF_Valid);
|
|
|
|
//_mm256_castsi256_si128();
|
|
//_mm256_permutevar8x32_epi32();
|
|
|
|
// 数据导出
|
|
memcpy(&pby8BitData[8 * i + 0], &varMi_Value, 32);
|
|
/*
|
|
pby8BitData[8 * i + 0] = ((int*)&varMi_Value)[0];
|
|
pby8BitData[8 * i + 1] = ((int*)&varMi_Value)[1];
|
|
pby8BitData[8 * i + 2] = ((int*)&varMi_Value)[2];
|
|
pby8BitData[8 * i + 3] = ((int*)&varMi_Value)[3];
|
|
pby8BitData[8 * i + 4] = ((int*)&varMi_Value)[4];
|
|
pby8BitData[8 * i + 5] = ((int*)&varMi_Value)[5];
|
|
pby8BitData[8 * i + 6] = ((int*)&varMi_Value)[6];
|
|
pby8BitData[8 * i + 7] = ((int*)&varMi_Value)[7];
|
|
*/
|
|
}
|
|
|
|
return true;
|
|
|
|
//图像映射
|
|
for (int i = 0; i < nDataLen; i++)
|
|
{
|
|
int nValue = (int)(fK * psh16BitData[i] + fC);
|
|
if (nValue < 0)
|
|
{
|
|
pby8BitData[i] = 0;
|
|
}
|
|
else if (nValue > 255)
|
|
{
|
|
pby8BitData[i] = 255;
|
|
}
|
|
else
|
|
{
|
|
pby8BitData[i] = nValue;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/*
|
|
* 将Y16数据转换成Y8数据
|
|
*/
|
|
bool Map16BitTo8Bit(short* psh16BitData, int nDataLen, unsigned char* pby8BitData, float fK, float fC)
|
|
{
|
|
if (nullptr == psh16BitData || nullptr == pby8BitData || nDataLen <= 0)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
__m128i varMi_Value = _mm_set_epi32(0, 0, 0, 0);
|
|
__m128 varM_Value = _mm_set_ps(0, 0, 0, 0);
|
|
|
|
__m128 varM_C = _mm_set_ps(fK, fK, fK, fK);
|
|
__m128 varM_K = _mm_set_ps(fC, fC, fC, fC);
|
|
|
|
__m128i varMi_0x00 = _mm_set_epi32(0x00, 0x00, 0x00, 0x00);
|
|
__m128i varMi_0xFF = _mm_set_epi32(0xFF, 0xFF, 0xFF, 0xFF);
|
|
|
|
for (int i = 0; i < nDataLen / 4; i++)
|
|
{
|
|
// 计算初值
|
|
varMi_Value = _mm_set_epi32(psh16BitData[4 * i + 0], psh16BitData[4 * i + 1], psh16BitData[4 * i + 2], psh16BitData[4 * i + 3]);
|
|
varM_Value = _mm_cvtepi32_ps(varMi_Value);
|
|
|
|
varM_Value = _mm_mul_ps(varM_Value, varM_K);
|
|
varM_Value = _mm_add_ps(varM_Value, varM_C);
|
|
|
|
// float转换为int
|
|
varMi_Value = _mm_cvtps_epi32(varM_Value);
|
|
|
|
// 计算值合规化
|
|
__m128i varMi_Mask_LT_0xFF = _mm_cmplt_epi32(varMi_Value, varMi_0xFF);
|
|
__m128i varMi_Mask_GT_0x00 = _mm_cmpgt_epi32(varMi_Value, varMi_0x00);
|
|
__m128i varMi_Mask_Normal = _mm_and_si128(varMi_Mask_LT_0xFF, varMi_Mask_GT_0x00);
|
|
__m128i varMi_Value_Normal = _mm_and_si128(varMi_Value, varMi_Mask_Normal);
|
|
|
|
__m128i varMi_Mask_0xFF = _mm_cmpgt_epi32(varMi_Value, varMi_0xFF);
|
|
__m128i varMi_0xFF_Valid = _mm_and_si128(varMi_0xFF, varMi_Mask_0xFF);
|
|
|
|
varMi_Value = _mm_or_si128(varMi_Mask_Normal, varMi_0xFF_Valid);
|
|
|
|
// 数据导出
|
|
pby8BitData[4 * i + 0] = ((int*)&varMi_Value)[0];
|
|
pby8BitData[4 * i + 1] = ((int*)&varMi_Value)[1];
|
|
pby8BitData[4 * i + 2] = ((int*)&varMi_Value)[2];
|
|
pby8BitData[4 * i + 3] = ((int*)&varMi_Value)[3];
|
|
}
|
|
|
|
return true;
|
|
|
|
//图像映射
|
|
for (int i = 0; i < nDataLen; i++)
|
|
{
|
|
int nValue = (int)(fK * psh16BitData[i] + fC);
|
|
|
|
if (nValue < 0)
|
|
{
|
|
pby8BitData[i] = 0;
|
|
}
|
|
else if (nValue > 255)
|
|
{
|
|
pby8BitData[i] = 255;
|
|
}
|
|
else
|
|
{
|
|
pby8BitData[i] = nValue;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* 混合调光
|
|
*/
|
|
namespace MixMapping
|
|
{
|
|
}
|
|
|
|
/*
|
|
* 直方图调光
|
|
*/
|
|
namespace HisogramMapping
|
|
{
|
|
}
|
|
} |