I was researching histograms and have an app that draws one using qt.. here is the code for histogram.cpp.. I want you to explain at a high level and check if it is correct?
The GITHUB repo link first: https://github.com/JCamiloo/ImageProcessing
Here's a high-level explanation and code review:
What the Code Does
This implements a grayscale image processing class with three main capabilities:
- Histogram calculation — counts how many pixels exist at each intensity value (0–255)
- Histogram equalization — redistributes pixel intensities to improve contrast
- Thresholding — converts a grayscale image to binary (black/white) using either ISODATA or Otsu's method
Bugs & Issues
1. calculateHistogram — Wrong pixel format assumption
originalPixels = image.bits(); // assumes 1 byte per pixel
image.bits() returns raw bytes, but most Qt images use more than 1 byte per pixel (e.g. RGB = 3 bytes, ARGB = 4 bytes). You should either enforce Format_Grayscale8 before calling this, or stride by bytesPerPixel. Without this, you're reading garbage values for non-grayscale images.
2. calculateHistogram — Array never reset
histogramArray[value]++;
histogramArray is never zeroed before accumulating. If calculateHistogram is called more than once (which it is — both equalizeHistogram and calculateThreshold call it), values from previous calls accumulate, producing a corrupt histogram.
Fix: Add memset(histogramArray, 0, sizeof(histogramArray)); at the start.
3. calculateThreshold (Otsu) — Division by zero risk
float m2 = (sum - meanF) / q2;
When i = 255, q2 becomes 0, causing a divide-by-zero crash.
Fix:
if (q1 == 0 || q2 == 0) continue;
4. calculateThreshold — Missing return for OTSU path edge case
The function has no return threshold at the bottom — if somehow neither branch is entered (malformed enum), behavior is undefined. Minor, but worth a default return 0 at the end.
5. equalizeHistogram — equalizedHistogram never reset
Same issue as histogramArray — equalizedHistogram accumulates across calls.
6. thresholding — Image format mismatch risk
qThresholdedImage = QImage(image.width(), image.height(), image.format());
If the source image isn't Format_Grayscale8, writing single bytes per pixel into thresholdedPixels will misalign with the actual bytes-per-pixel of the format, corrupting the output.
Summary Table
| Issue | Severity |
|---|---|
| Histogram array not reset between calls | 🔴 High |
| Pixel format not enforced (bytesPerPixel) | 🔴 High |
| Otsu divide-by-zero at q2=0 | 🔴 High |
| equalizedHistogram not reset | 🟡 Medium |
| Thresholding format mismatch | 🟡 Medium |
| Missing default return in calculateThreshold | 🟢 Low |
The core logic of equalization and both thresholding algorithms is correct — the math checks out. The bugs are mostly around memory/format assumptions that are easy to fix.
No comments:
Post a Comment