在C++中如何将BMP文件存储到四叉树?求构建方法及顺序建议
First, a quick clarification: The example data you shared starts with P1, which is the header for a PBM (Portable Bitmap) text-format file, not a standard BMP file. BMP uses a binary header structure, while PBM text is straightforward to parse. I’ll focus on your example first, then touch on BMP if you need it later.
The Right Approach: Start from the Root Node
You should always build the quadtree top-down, starting with the root node—here’s why:
- The root represents the entire image (in your case, 4x4 pixels). Starting here lets you naturally split the image into subregions only when necessary, which aligns perfectly with the quadtree’s core purpose: compressing uniform regions to avoid redundant nodes.
- Building from leaves first would require precomputing every single pixel as a leaf, then merging them upward. This is inefficient and defeats the quadtree’s main benefit, since you’d be creating nodes for areas that could have been represented as a single uniform node.
Step-by-Step Implementation
1. Parse the PBM File First
First, read the file and store the pixel data in a 2D array (or a 1D array with index calculations) so you can easily check regions. For your example P1 4 4 1 0 1 1 0 1 0 0 1 1 0 0 1 1 0 0:
P1= text-format PBM marker4 4= width and height (4x4 pixels)- The rest are pixel values (0 = white, 1 = black)
2. Recursive Quadtree Construction
Use a recursive function that takes a region’s top-left coordinates, size, and the pixel array, then returns a QuadTreeNode. Here’s the core logic:
- For the current region, check if all pixels are the same color.
- If yes: Create a leaf node with that color, leave all
childrenasNULL. - If no: Create an internal node with
color = -1, split the region into 4 equal subregions, then recursively build each child node for those subregions.
- If yes: Create a leaf node with that color, leave all
Example C-like Pseudocode
#include <stdlib.h> struct QuadTreeNode { int size; struct QuadTreeNode *children[4]; int color; // 0 white, 1 black, -1 div }; // Helper to check if all pixels in a region are uniform int isUniform(int x, int y, int size, int** pixels) { int baseColor = pixels[y][x]; for (int i = y; i < y + size; i++) { for (int j = x; j < x + size; j++) { if (pixels[i][j] != baseColor) { return 0; } } } return 1; } // Build quadtree from a region (x,y = top-left corner) struct QuadTreeNode* buildQuadTree(int x, int y, int size, int** pixels) { struct QuadTreeNode* node = malloc(sizeof(struct QuadTreeNode)); node->size = size; if (isUniform(x, y, size, pixels)) { // Leaf node: all pixels share the same color node->color = pixels[y][x]; for (int i = 0; i < 4; i++) { node->children[i] = NULL; } } else { // Internal node: split into 4 child regions node->color = -1; int halfSize = size / 2; // Define child order (adjust as needed: [0] top-left, [1] top-right, [2] bottom-left, [3] bottom-right) node->children[0] = buildQuadTree(x, y, halfSize, pixels); node->children[1] = buildQuadTree(x + halfSize, y, halfSize, pixels); node->children[2] = buildQuadTree(x, y + halfSize, halfSize, pixels); node->children[3] = buildQuadTree(x + halfSize, y + halfSize, halfSize, pixels); } return node; }
3. Usage Notes
- For your 4x4 example, call
buildQuadTree(0, 0, 4, pixelArray)to get the root node of your quadtree. - If you’re actually working with BMP files, first parse the BMP header to extract width, height, and pixel data (note BMP stores pixels bottom-up in most cases, so you’ll need to flip the pixel array before building the tree).
- Don’t forget to write a helper function to free the quadtree nodes later to avoid memory leaks!
Why Not Leaf-First?
Building from leaves would mean creating a node for every single pixel first, then checking if groups of 4 leaves can be merged into a parent node. This requires iterating over leaf nodes repeatedly, which is slower and more complex than the top-down recursive approach. The top-down method only creates nodes when a region needs splitting, which is far more efficient and intuitive for quadtree construction.
内容的提问来源于stack exchange,提问作者Wryfyng

