Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New Local Thresholding Algorithm #10

Open
wants to merge 42 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
f56efab
Horizontal Thresholding
nguy8tri Nov 14, 2021
e494123
Merge branch 'tri-centroiding' of https://github.com/uwcubesat/lost i…
nguy8tri Nov 20, 2021
b1d8c57
Local Centroiding
nguy8tri Nov 29, 2021
3381500
Changes to reflect additional parameters from Master
nguy8tri Dec 16, 2021
a94a8b3
For local thresholding
nguy8tri Dec 16, 2021
f697131
Changes to correct thresholding match
nguy8tri Dec 17, 2021
a424332
Stuff
nguy8tri Jan 4, 2022
1d5eec4
Something
nguy8tri Jan 4, 2022
7b132f4
Revisions of code for local thresholding --Doesn't seem off, but stil…
nguy8tri Jan 13, 2022
a790c8a
Changes are now consistent with normal centroiding algorithm
nguy8tri Jan 13, 2022
d2d57b0
Testing Files
nguy8tri Jan 20, 2022
c9ac940
Fixed Local Thresholding Algorithm??
nguy8tri Jan 30, 2022
b3eb1bd
I hope this actually works
nguy8tri Jan 31, 2022
b614f4e
Done!
nguy8tri Feb 11, 2022
ab1b3bd
Done!
nguy8tri Feb 11, 2022
8e5cd1b
To LF
nguy8tri Feb 15, 2022
591f618
No more cairo
nguy8tri Feb 15, 2022
465769f
More deletes
nguy8tri Feb 15, 2022
56b09c8
More to LF
nguy8tri Feb 17, 2022
b2141a2
To LF
nguy8tri Feb 25, 2022
30a8429
Removing things
nguy8tri Feb 25, 2022
ea96132
Removed
nguy8tri Feb 25, 2022
5acf0f2
Merging with Master
nguy8tri Mar 1, 2022
8681534
Centroiding and updates
nguy8tri Mar 3, 2022
1716f5a
Changes with Response to Comments
nguy8tri Mar 3, 2022
dd04ed6
Changes with Response to Comments
nguy8tri Mar 3, 2022
c97e4b9
Last set of subdivisions
nguy8tri Mar 4, 2022
9b0fd07
Testing Done
nguy8tri Apr 5, 2022
677b11a
More changes
nguy8tri Apr 19, 2022
46f521a
Changes
nguy8tri Apr 19, 2022
a51c5ad
Some debugging
nguy8tri May 14, 2022
5bd5a21
Changes
nguy8tri Jun 10, 2022
bbb9982
Troubleshooting for 2D Local Centroiding
nguy8tri Jun 15, 2022
3ecd13c
Troubleshooting box matching algorithm
nguy8tri Jul 5, 2022
c654db3
Finished Debugging?
nguy8tri Jul 9, 2022
b88284c
Fixing style
nguy8tri Jul 13, 2022
e366966
Deleting Files
nguy8tri Jul 13, 2022
8559fa3
Proving Inverse Statement
nguy8tri Jul 14, 2022
15b0f78
Modified Inverse Test to go both ways
nguy8tri Jul 14, 2022
5cbac61
Change to properties file
nguy8tri Aug 9, 2022
e00eab1
Changed iterator vars type
nguy8tri Aug 23, 2022
97eced3
Changed IWCOG to also use Local Thresholding
nguy8tri Sep 7, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,21 @@
"streambuf": "cpp",
"cinttypes": "cpp",
"typeinfo": "cpp",
"files.eol": "\n"
"files.eol": "\n",
"regex": "cpp",
"bitset": "cpp",
"chrono": "cpp",
"complex": "cpp",
"condition_variable": "cpp",
"cstring": "cpp",
"ctime": "cpp",
"set": "cpp",
"ratio": "cpp",
"future": "cpp",
"iomanip": "cpp",
"mutex": "cpp",
"shared_mutex": "cpp",
"thread": "cpp",
"variant": "cpp"
}
}
148 changes: 140 additions & 8 deletions src/centroiders.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

nguy8tri marked this conversation as resolved.
Show resolved Hide resolved
namespace lost {

// DUMMY
// DUMMYS

std::vector<Star> DummyCentroidAlgorithm::Go(unsigned char *image, int imageWidth, int imageHeight) const {
std::vector<Star> result;
Expand Down Expand Up @@ -92,6 +92,81 @@ int BasicThreshold(unsigned char *image, int imageWidth, int imageHeight) {
return mean + (std * 5);
}

// Local Basic Thresholding with divisions as parameter, returns a vector containing thresholds
// corresponding to different divisions.
// Divisions are horizontally based
// Uses the same statistical algorithm as BasicThresholding
std::vector<int> LocalBasicThresholding(unsigned char *image, int imageWidth, int imageHeight, int subdivisions) {
// run Basic Threshold on all elements in certain subdivisions
int div = imageHeight / subdivisions; // Minimum number of lines for each division
int leftover = imageHeight % subdivisions; // Determines the first few lines that have 1 more line
int totalPixels = imageWidth * imageHeight;
nguy8tri marked this conversation as resolved.
Show resolved Hide resolved
int totalMag = 0;
float std = 0;
float mean = 0;
std::vector<int> standardDeviations;
// Sets threshold for the first few subdivisions that have 1 more line than the rest
for(int i = 0; i < leftover; i++) {
totalMag = 0;
std = 0;
mean = 0;
for(int j = i * (div + 1) * imageWidth; j < (i+1) * (div + 1) * imageWidth; j++) {
totalMag += image[j];
}
mean = totalMag / ((div + 1) * imageWidth);
for (long j = i * (div + 1) * imageWidth; j < (i+1) * (div + 1) * imageWidth; j++) {
std += std::pow(image[j] - mean, 2);
}
std = std::sqrt(std / ((div + 1) * imageWidth));
standardDeviations.push_back(mean + (std * 5));
}
// Sets thresholds for remaining subdivisions, which have one less line than before
for(int i = leftover; i < subdivisions; i++) {
totalMag = 0;
std = 0;
mean = 0;
for(int j = i * (div) * imageWidth; j < (i+1) * (div) * imageWidth; j++) {
nguy8tri marked this conversation as resolved.
Show resolved Hide resolved
totalMag += image[j];
}
mean = totalMag / (div * imageWidth); // Currently divides by 0 at 1000 subdivisions for 7qPnoi1.png
for (long j = i * (div) * imageWidth; j < (i+1) * (div) * imageWidth; j++) {
std += std::pow(image[j] - mean, 2);
}
nguy8tri marked this conversation as resolved.
Show resolved Hide resolved
std = std::sqrt(std / (div * imageWidth));
standardDeviations.push_back(mean + (std * 5));
}
nguy8tri marked this conversation as resolved.
Show resolved Hide resolved
/*
for(int i = 0; i < subdivisions; i++) {
totalMag = 0;
std = 0;
mean = 0;
if(i != subdivisions - 1) {
for(int j = i * div * imageWidth; j < (i+1) * div * imageWidth; j++) {
totalMag += image[j];
}
mean = totalMag / (div * imageWidth);
for (long j = i * div * imageWidth; j < (i+1) * div * imageWidth; j++) {
std += std::pow(image[j] - mean, 2);
}
std = std::sqrt(std / (div * imageWidth));
} else { // For the case that the end has more lines than the rest
for(int j = i * div * imageWidth; j < sizeof(image); j++) {
totalMag += image[j];
}
mean = totalMag / (sizeof(image) - i * div * imageWidth + 1);
for (long j = i * div * imageWidth; j < sizeof(image); j++) {
std += std::pow(image[j] - mean, 2);
}
std = std::sqrt(std / (sizeof(image) - i * div * imageWidth + 1));
}
standardDeviations.push_back(mean + (std * 5));
}
standardDeviations.push_back(mean + (std * 5));
*/
nguy8tri marked this conversation as resolved.
Show resolved Hide resolved
// Return values of previous method as a vector
return standardDeviations;
}

// basic thresholding, but do it faster (trade off of some accuracy?)
int BasicThresholdOnePass(unsigned char *image, int imageWidth, int imageHeight) {
unsigned long totalMag = 0;
Expand All @@ -117,14 +192,27 @@ struct CentroidParams {
int yMin;
int yMax;
int cutoff;
std::vector<int> localCutoff;
bool isValid;
std::unordered_set<int> checkedIndices;
};

// For a given i and picture dimensions, determines which subdivision i is in (Zero Based)
int subdivision(long i, int imageWidth, int imageHeight, int subdivisions) {
nguy8tri marked this conversation as resolved.
Show resolved Hide resolved
int div = imageHeight / subdivisions;
int leftover = imageHeight % subdivisions;
if(i < (div + 1) * leftover * imageWidth) {
return i / ((div + 1) * imageWidth);
} else {
return leftover + (i - (div + 1) * leftover * imageWidth) / (div * imageWidth);
}
return 0;
}

//recursive helper here
void CogHelper(CentroidParams &p, long i, unsigned char *image, int imageWidth, int imageHeight) {
void CogHelper(CentroidParams &p, long i, unsigned char *image, int imageWidth, int imageHeight, int subdivisions) {

if (i >= 0 && i < imageWidth * imageHeight && image[i] >= p.cutoff && p.checkedIndices.count(i) == 0) {
if (i >= 0 && i < imageWidth * imageHeight && image[i] >= p.localCutoff.at(subdivision(i, imageWidth, imageHeight, subdivisions)) && p.checkedIndices.count(i) == 0) {
//check if pixel is on the edge of the image, if it is, we dont want to centroid this star
if (i % imageWidth == 0 || i % imageWidth == imageWidth - 1 || i / imageWidth == 0 || i / imageWidth == imageHeight - 1) {
p.isValid = false;
Expand All @@ -144,16 +232,16 @@ void CogHelper(CentroidParams &p, long i, unsigned char *image, int imageWidth,
p.xCoordMagSum += ((i % imageWidth)) * image[i];
p.yCoordMagSum += ((i / imageWidth)) * image[i];
if(i % imageWidth != imageWidth - 1) {
CogHelper(p, i + 1, image, imageWidth, imageHeight);
CogHelper(p, i + 1, image, imageWidth, imageHeight, subdivisions);
}
if (i % imageWidth != 0) {
CogHelper(p, i - 1, image, imageWidth, imageHeight);
CogHelper(p, i - 1, image, imageWidth, imageHeight, subdivisions);
}
CogHelper(p, i + imageWidth, image, imageWidth, imageHeight);
CogHelper(p, i - imageWidth, image, imageWidth, imageHeight);
CogHelper(p, i + imageWidth, image, imageWidth, imageHeight, subdivisions);
CogHelper(p, i - imageWidth, image, imageWidth, imageHeight, subdivisions);
}
}

/*
nguy8tri marked this conversation as resolved.
Show resolved Hide resolved
std::vector<Star> CenterOfGravityAlgorithm::Go(unsigned char *image, int imageWidth, int imageHeight) const {
CentroidParams p;

Expand Down Expand Up @@ -193,6 +281,50 @@ std::vector<Star> CenterOfGravityAlgorithm::Go(unsigned char *image, int imageWi
}
return result;
}
*/
//Copy of CenterOfGravityAlgorithm, except the threshold changes depending on the vertical height in the image
//Subdivisions refers to how many horizontal sections with different thresholds are present
std::vector<Star> CenterOfGravityAlgorithm::Go(unsigned char *image, int imageWidth, int imageHeight) const {
CentroidParams p;
// Program will use divisions to represent the subdivisions
int divisions = subdivisions;
if(subdivisions > imageHeight) {
divisions = imageHeight;
}
std::vector<Star> result;
p.localCutoff = LocalBasicThresholding(image, imageWidth, imageHeight, divisions);
for (long i = 0; i < imageHeight * imageWidth; i++) {
if (image[i] >= p.localCutoff.at(subdivision(i, imageWidth, imageHeight, divisions)) && p.checkedIndices.count(i) == 0) {
//iterate over pixels that are part of the star
int xDiameter = 0; //radius of current star
int yDiameter = 0;
p.yCoordMagSum = 0; //y coordinate of current star
p.xCoordMagSum = 0; //x coordinate of current star
p.magSum = 0; //sum of magnitudes of current star

p.xMax = i % imageWidth;
p.xMin = i % imageWidth;
p.yMax = i / imageWidth;
p.yMin = i / imageWidth;
p.isValid = true;

int sizeBefore = p.checkedIndices.size();

CogHelper(p, i, image, imageWidth, imageHeight, divisions);
xDiameter = (p.xMax - p.xMin) + 1;
yDiameter = (p.yMax - p.yMin) + 1;

//use the sums to finish CoG equation and add stars to the result
float xCoord = (p.xCoordMagSum / (p.magSum * 1.0));
float yCoord = (p.yCoordMagSum / (p.magSum * 1.0));

if (p.isValid) {
result.push_back(Star(xCoord + 0.5f, yCoord + 0.5f, ((float)(xDiameter))/2.0f, ((float)(yDiameter))/2.0f, p.checkedIndices.size() - sizeBefore));
}
}
}
return result;
}

//Determines how accurate and how much iteration is done by the IWCoG algorithm,
//smaller means more accurate and more iterations.
Expand Down
4 changes: 3 additions & 1 deletion src/centroiders.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@ class DummyCentroidAlgorithm: public CentroidAlgorithm {

class CenterOfGravityAlgorithm : public CentroidAlgorithm {
public:
CenterOfGravityAlgorithm() { };
CenterOfGravityAlgorithm(int subdivisions) : subdivisions(subdivisions) { };
Stars Go(unsigned char *image, int imageWidth, int imageHeight) const override;
private:
int subdivisions;
};

class IterativeWeightedCenterOfGravityAlgorithm : public CentroidAlgorithm {
Expand Down
3 changes: 2 additions & 1 deletion src/io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,8 @@ CentroidAlgorithm *DummyCentroidAlgorithmPrompt() {
}

CentroidAlgorithm *CoGCentroidAlgorithmPrompt() {
return new CenterOfGravityAlgorithm();
int subdivisions = Prompt<int>("How many subdivisions to use");
return new CenterOfGravityAlgorithm(subdivisions);
}

CentroidAlgorithm *IWCoGCentroidAlgorithmPrompt() {
Expand Down
2 changes: 0 additions & 2 deletions test/main.cpp

This file was deleted.