Files
GuideInfrared/编程资料/并行编程/Intrinsic/ImageMapping.cpp
2026-02-01 21:55:55 +08:00

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
{
}
}