1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
|
#include "bowtie.h"
#include <algorithm>
namespace image
{
namespace bowtie
{
Image correctGenericBowTie(Image &inputImage, const int channelCount, const long scanHeight, const float alpha, const float beta, std::vector<std::vector<int>> *reverse_lut)
{
// 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 outputImage = Image(inputImage.depth(), width, height, channelCount);
// Reserve our buffers
int *scan_buffer_input = new int[height * width];
int *scan_buffer_output = new int[height * width];
int *col_buffer_input = new int[scanHeight];
int *col_buffer_output = new int[scanHeight];
if (reverse_lut != nullptr)
{
reverse_lut->resize(width);
for (int i = 0; i < width; i++)
(*reverse_lut)[i].resize(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.get((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 centerPixelCounts = int((((halfWidth - abs(rowNumber - halfWidth)) / (float)halfWidth) * alpha + beta) * scanHeight);
centerPixelCounts = std::min<int>(centerPixelCounts, scanHeight);
int paddingPixels = (scanHeight - centerPixelCounts) / 2;
// std::cout << pixelsOffCenter << " " << centerPixelCounts << " " << paddingPixels << std::endl;
for (int i = 0; i < scanHeight; i++)
{
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;
}
// 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.set((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 <typename T>
Image<T> correctSingleBowTie(Image<T> &inputImage, const int channelCount, const long scanHeight, const float alpha, const float beta)
{
// 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);
// 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);
*/
}
}
|