All SolutionsAll Solutions

Counting Stars

Week 18, 2026

it's gets confusing | Draw6 | C++ Solutions

#define STB_IMAGE_IMPLEMENTATION #include "stb_image.h"//https://github.com/nothings/stb/blob/master/stb_image.h #include "allheaders.hpp" #define STB_IMAGE_WRITE_IMPLEMENTATION #include "stb_image_write.h" using namespace std; //------------------------------------[HELPER FUNCTION TO EXTRACT RGB VALUES]- struct RGBPixel { uint8_t red; uint8_t green; uint8_t blue; }; vector<string> values; vector<int> ivaluesR; vector<int> ivaluesG; vector<int> ivaluesB; int iX, iY, iR, iG, iB; //------------------------------------------ void loadPNG(const std::string& filename) { int width, height, channels; uint8_t* imageData = stbi_load(filename.c_str(), &width, &height, &channels, 3); if (imageData == nullptr) { std::cerr << "Error loading image: " << filename << std::endl; return; } std::vector<RGBPixel> pixels(width * height); iX = width; iY = height; for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x) { int index = (y * width + x) * 3; RGBPixel& pixel = pixels[y * width + x]; pixel.red = imageData[index]; pixel.green = imageData[index + 1]; pixel.blue = imageData[index + 2]; iR = pixel.red; iG = pixel.green; iB = pixel.blue; } } for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x) { RGBPixel& pixel = pixels[y * width + x]; string s = to_string((int)pixel.red) + "," + to_string((int)pixel.green) + "," + to_string((int)pixel.blue); values.push_back(s); iR = pixel.red; iG = pixel.green; iB = pixel.blue; ivaluesR.push_back(iR); ivaluesG.push_back(iG); ivaluesB.push_back(iB); } } stbi_image_free(imageData); } //-----------------------------------------------------------------------[BEGIN] int main(int argc, char* argv[]) { string imgname = argv[1]; double totalpixels = 0; double coverage = 0; double icoverage = 0;//coverage calc double emptyspace, stars, touching, nottouching = 0; int nUL, nUC, nUR, nL, nR, nLL, nLC, nLR = 0;//neighbors = upper-left, upper-center, upper-right, etc int iRedPixels, iGreenPixels, iBluePixels = 0; double starcount = 0; double icover, coveragemarker = 0; fstream outfile("outfile", ios::in | ios::out | ios::trunc); if(imgname == "") { cout << "No image file specified\n"; return -1; } std::string filename = imgname; loadPNG(filename); //converts image to both string and int vectors //values is the string vector -> save to file for comparing //values not used for solution math for (const auto& str : values) { outfile << str << "\n"; } int iPixelColor = ivaluesR.size(); int iInput; cout << "Enter threshold\n"; cin >> iInput; int threshold = iInput; cout << "working\n";//--------------------------------------[ SET THRESHOLD ]; for(int i = 0; i < iPixelColor; i++) { if((ivaluesR[i] < threshold) && (ivaluesG[i] < threshold) && (ivaluesB[i] < threshold)) {//anything below threshold gets zero'd' (black) ivaluesR[i] = 0; ivaluesG[i] = 0; ivaluesB[i] = 0; } else {//anything above threshold gets set to brightest (red) ivaluesR[i] = 255; coveragemarker++;//suspect is a Star stars++; nUL = i - (iX - 1); nUC = i - (iX); nUR = i - (iX + 1); nL = i - 1; nR = i + 1; nLL = i + (iX - 1); nLC = i + (iX); nLR = i + (iX + 1); if(i > iX && i < iX * iY) { if((ivaluesR[nUL] == 255)) { ivaluesR[nUL] = 0; ivaluesG[nUL] = 255; ivaluesB[nUL] = 255; } if((ivaluesR[nUC] == 255)) { ivaluesR[nUC] = 0; ivaluesG[nUC] = 125; ivaluesB[nUC] = 175; } if((ivaluesR[nUR] == 255)) { ivaluesR[nUR] = 0; ivaluesG[nUR] = 125; ivaluesB[nUR] = 175; } if((ivaluesR[nL] == 255)) { ivaluesR[nL] = 0; ivaluesG[nL] = 125; ivaluesB[nL] = 175; } if((ivaluesR[nR] == 255)) { ivaluesR[nR] = 0; ivaluesG[nR] = 125; ivaluesB[nR] = 175; } if((ivaluesR[nLL] == 255)) { ivaluesR[nLL] = 0; ivaluesG[nLL] = 125; ivaluesB[nLL] = 175; } if((ivaluesR[nLC] == 255)) { ivaluesR[nLC] = 0; ivaluesG[nLC] = 125; ivaluesB[nLC] = 175; } if((ivaluesR[nLR] == 255)) { ivaluesR[nLR] = 0; ivaluesG[nLR] = 125; ivaluesB[nLR] = 175; } if(ivaluesR[i] == 255) { nottouching++; } } } } for(int i = 0; i < iPixelColor; i++) { cout << ivaluesR[i] << "," << ivaluesG[i] << "," << ivaluesB[i] << "\n"; } for(int i = 0; i < iPixelColor; i++) { if(ivaluesR[i] > threshold) { starcount++; icover++; iRedPixels++; } if(ivaluesG[i] > threshold) { icover++; iGreenPixels++; icoverage++; } if(ivaluesB[i] > threshold) { iBluePixels++; } } // -----------------------------------------------------------------------[END] int count = ivaluesR.size();// int vector holding the reds double bettercount = stars - starcount; cout << "----------------------------------\n"; cout << "File: " << filename << "\n"; cout << "Imgage size = " << iX << "x" << iY << "\n"; cout << "Brightness threshold: " << threshold << "\n"; cout << "Stars count: " << nottouching - bettercount << "\n"; cout << "star pixels: " << nottouching << " / "<< count << "\n"; coverage = (nottouching / count) * 100; cout << "Star coverage: " << coverage << "%\n"; cout << "----------------------------------\n"; return 0; }

Food fill to mark all pixels of a star | greenya | Odin Solutions

package main import "core:fmt" import "core:image" import "core:image/bmp" import "core:image/jpeg" import "core:image/png" _, _ :: jpeg, png // IMAGE1_BYTES :: #load("stars-example1.png") // IMAGE2_BYTES :: #load("stars-example2.png") IMAGE1_BYTES :: #load("stars1.png") IMAGE2_BYTES :: #load("stars2.jpg") RGB_THRESHOLD :: 140 // 0..255*3 main :: proc () { fmt.printfln("RGB threshold: %d (0-%d)", RGB_THRESHOLD, 255*3) process_image_bytes(IMAGE1_BYTES, RGB_THRESHOLD, "result1.bmp") process_image_bytes(IMAGE2_BYTES, RGB_THRESHOLD, "result2.bmp") } R_NEW :: 254 R_VISITED :: 255 process_image_bytes :: proc (bytes: [] u8, rgb_threshold: int, save_result_bmp := "") { img, err := image.load_from_bytes(bytes) fmt.assertf(err == nil, "Failed to load image: %v", err) fmt.assertf(img.channels == 3, "Image must have exactly 3 channels (RGB, no alpha)") defer image.destroy(img) fmt.println("------------------------------") defer fmt.println("------------------------------") fmt.printfln("Image resolution: %d x %d", img.width, img.height) assert(img.width * img.height == len(img.pixels.buf) / 3) pixels := transmute ([][3] u8) img.pixels.buf[:len(img.pixels.buf)/3] fmt.println("Applying threshold...") star_pixel_count: int for i in 0..<img.width*img.height { r := int(pixels[i].r) g := int(pixels[i].g) b := int(pixels[i].b) if r + g + b > RGB_THRESHOLD { pixels[i] = {R_NEW,255,255} star_pixel_count += 1 } else { pixels[i] = {} } } fmt.println("Counting stars...") star_count := count_stars(pixels, img.width, img.height) fmt.printfln("Stars : %d", star_count) fmt.printfln("Coverage (%%) : %.1f", (f32(star_pixel_count)*100) / f32(len(pixels))) if save_result_bmp != "" { fmt.printfln("Writing %s...", save_result_bmp) bmp.save(save_result_bmp, img) } } count_stars :: proc (pixels: [][3] u8, width, height: int) -> (count: int) { for y in 0..<height do for x in 0..<width { if pixels[y*width+x].r == R_NEW { fill_star(pixels, width, height, x, y) count += 1 } } return } fill_star :: proc (pixels: [][3] u8, width, height, x, y: int) { list := make([dynamic] int, len=0, cap=400) append(&list, y*width+x) defer delete(list) for len(list) > 0 { i := pop(&list) pixels[i].r = R_VISITED for d in ([?] [2] int { { -1, -1 }, { 0, -1 }, { +1, -1 }, { -1, 0 }, { +1, 0 }, { -1, +1 }, { 0, +1 }, { +1, +1 }, }) { j := i + d.y * width + d.x if j < 0 || j >= width*height do continue if pixels[j].r == R_NEW do append(&list, j) } } }