satdump/src-core/common/image/bowtie.cpp

181 lines
8.2 KiB
C++
Raw Normal View History

#include "bowtie.h"
#include <algorithm>
2021-05-23 23:16:36 +02:00
namespace image
{
2021-05-23 23:16:36 +02:00
namespace bowtie
{
2021-08-06 15:33:44 +02:00
template <typename T>
2023-11-25 17:42:54 +01:00
Image<T> correctGenericBowTie(Image<T> &inputImage, const int channelCount, const long scanHeight, const float alpha, const float beta, std::vector<std::vector<int>> *reverse_lut)
2021-05-23 23:16:36 +02:00
{
// Compute everything we'll need
const long height = inputImage.height();
const long width = inputImage.width();
const long scanCount = height / scanHeight;
const long halfWidth = width / 2;
2021-05-23 23:16:36 +02:00
// Create our output image
Image<T> outputImage = Image<T>(width, height, channelCount);
2021-05-23 23:16:36 +02:00
// Reserve our buffers
2021-08-06 15:33:44 +02:00
T *scan_buffer_input = new T[height * width];
T *scan_buffer_output = new T[height * width];
T *col_buffer_input = new T[scanHeight];
T *col_buffer_output = new T[scanHeight];
2023-11-25 17:42:54 +01:00
if (reverse_lut != nullptr)
{
reverse_lut->resize(width);
for (int i = 0; i < width; i++)
(*reverse_lut)[i].resize(scanHeight);
}
2021-05-23 23:16:36 +02:00
for (int channel = 0; channel < channelCount; channel++)
{
2021-05-23 23:16:36 +02:00
for (int scanNumber = 0; scanNumber < scanCount; scanNumber++)
{
2023-11-25 17:42:54 +01:00
// std::cout << "Processing scan " << scanNumber << std::endl;
2021-05-23 23:16:36 +02:00
// Load out input buffer
for (int lineNumber = 0; lineNumber < scanHeight; lineNumber++)
{
2021-05-23 23:16:36 +02:00
for (int pixelNumber = 0; pixelNumber < width; pixelNumber++)
{
scan_buffer_input[lineNumber * width + pixelNumber] = inputImage[(channel * width * height) + ((scanNumber * scanHeight) + lineNumber) * width + pixelNumber];
}
}
2021-05-23 23:16:36 +02:00
for (int rowNumber = 0; rowNumber < width; rowNumber++)
{
// Load our column
for (int lineNumber = 0; lineNumber < scanHeight; lineNumber++)
{
col_buffer_input[lineNumber] = scan_buffer_input[lineNumber * width + rowNumber];
}
2021-05-23 23:16:36 +02:00
int centerPixelCounts = int((((halfWidth - abs(rowNumber - halfWidth)) / (float)halfWidth) * alpha + beta) * scanHeight);
centerPixelCounts = std::min<int>(centerPixelCounts, scanHeight);
2021-05-23 23:16:36 +02:00
int paddingPixels = (scanHeight - centerPixelCounts) / 2;
2023-11-25 17:42:54 +01:00
// std::cout << pixelsOffCenter << " " << centerPixelCounts << " " << paddingPixels << std::endl;
2021-05-23 23:16:36 +02:00
for (int i = 0; i < scanHeight; i++)
{
2023-11-25 17:42:54 +01:00
int pxpos = paddingPixels + int(((float)i / (float)scanHeight) * centerPixelCounts);
col_buffer_output[i] = col_buffer_input[pxpos];
if (reverse_lut != nullptr)
(*reverse_lut)[rowNumber][i] = pxpos;
2021-05-23 23:16:36 +02:00
}
// Offload our columm
for (int lineNumber = 0; lineNumber < scanHeight; lineNumber++)
{
scan_buffer_output[lineNumber * width + rowNumber] = col_buffer_output[lineNumber];
}
}
2021-05-23 23:16:36 +02:00
// Offload out output buffer
for (int lineNumber = 0; lineNumber < scanHeight; lineNumber++)
{
2021-05-23 23:16:36 +02:00
for (int pixelNumber = 0; pixelNumber < width; pixelNumber++)
{
outputImage[(channel * width * height) + ((scanNumber * scanHeight) + lineNumber) * width + pixelNumber] = scan_buffer_output[lineNumber * width + pixelNumber];
}
}
}
}
2021-05-23 23:16:36 +02:00
delete[] scan_buffer_input;
delete[] scan_buffer_output;
delete[] col_buffer_input;
delete[] col_buffer_output;
2021-05-23 23:16:36 +02:00
return outputImage;
}
2021-08-06 15:33:44 +02:00
2023-11-25 17:42:54 +01:00
template Image<uint8_t> correctGenericBowTie(Image<uint8_t> &, const int, const long, const float, const float, std::vector<std::vector<int>> *);
template Image<uint16_t> correctGenericBowTie(Image<uint16_t> &, const int, const long, const float, const float, std::vector<std::vector<int>> *);
2021-10-22 18:02:59 +02:00
/*
template <typename T>
Image<T> correctSingleBowTie(Image<T> &inputImage, const int channelCount, const long scanHeight, const float alpha, const float beta)
2021-10-22 18:02:59 +02:00
{
// Compute everything we'll need
const long height = inputImage.height();
const long width = inputImage.width();
const long scanCount = height / scanHeight;
const long halfWidth = width / 2;
// Create our output image
Image<T> outputImage = Image<T>(width, height, 1, channelCount);
2021-10-22 18:02:59 +02:00
// Reserve our buffers
T *scan_buffer_input = new T[height * width];
T *scan_buffer_output = new T[height * width];
T *col_buffer_input = new T[scanHeight];
T *col_buffer_output = new T[scanHeight];
for (int channel = 0; channel < channelCount; channel++)
{
for (int scanNumber = 0; scanNumber < scanCount; scanNumber++)
{
//std::cout << "Processing scan " << scanNumber << std::endl;
// Load out input buffer
for (int lineNumber = 0; lineNumber < scanHeight; lineNumber++)
{
for (int pixelNumber = 0; pixelNumber < width; pixelNumber++)
{
scan_buffer_input[lineNumber * width + pixelNumber] = inputImage[(channel * width * height) + ((scanNumber * scanHeight) + lineNumber) * width + pixelNumber];
}
}
for (int rowNumber = 0; rowNumber < width; rowNumber++)
{
// Load our column
for (int lineNumber = 0; lineNumber < scanHeight; lineNumber++)
{
col_buffer_input[lineNumber] = scan_buffer_input[lineNumber * width + rowNumber];
}
int topPixelCount = int((((halfWidth - abs(rowNumber - halfWidth)) / (float)halfWidth) * alpha + beta) * scanHeight);
topPixelCount = std::min<int>(topPixelCount, scanHeight);
for (int i = 0; i < scanHeight; i++)
{
col_buffer_output[i] = col_buffer_input[int(((float)i / (float)scanHeight) * topPixelCount)];
}
// Offload our columm
for (int lineNumber = 0; lineNumber < scanHeight; lineNumber++)
{
scan_buffer_output[lineNumber * width + rowNumber] = col_buffer_output[lineNumber];
}
}
// Offload out output buffer
for (int lineNumber = 0; lineNumber < scanHeight; lineNumber++)
{
for (int pixelNumber = 0; pixelNumber < width; pixelNumber++)
{
outputImage[(channel * width * height) + ((scanNumber * scanHeight) + lineNumber) * width + pixelNumber] = scan_buffer_output[lineNumber * width + pixelNumber];
}
}
}
}
delete[] scan_buffer_input;
delete[] scan_buffer_output;
delete[] col_buffer_input;
delete[] col_buffer_output;
return outputImage;
}
template image::Image<uint8_t> correctSingleBowTie(image::Image<uint8_t> &, const int, const long, const float, const float);
template image::Image<uint16_t> correctSingleBowTie(image::Image<uint16_t> &, const int, const long, const float, const float);
2021-10-22 18:02:59 +02:00
*/
}
}