justadudewhohacks / justadudewhohacks/opencv4nodejs
Grabcut returns inconsistent results
- Dominant language
- C++
- Stars
- 5.1k
- Forks
- 826
- PR merge metrics
- No merged PRs in 30d
Description
When using grabcut, the results differ between different runs while the input is the same. The results are very similar but differ slightly. In the test case below I try to extract a head shape, but the mask around the hair will differ between runs.
Isolated test case:
```
const cv = require('opencv4nodejs');
const path = require('path');
const processImage = async index => {
const img = await cv.imreadAsync(path.resolve(__dirname, 'test.jpg'));
const center = new cv.Point2(198, 198);
const width = 180 * 1.2;
const height = 162 * 2;
const angle = -6;
const mask = new cv.Mat(img.rows, img.cols, cv.CV_8UC1, 0);
const faceRectWide = new cv.RotatedRect(center, new cv.Size(width * 1.6, height * 1.6), angle);
const faceRect = new cv.RotatedRect(center, new cv.Size(width * 0.9, height * 0.9), angle);
mask.drawEllipse(faceRectWide, new cv.Vec3(cv.GC_PR_FGD, cv.GC_PR_FGD, cv.GC_PR_FGD), -1, cv.LINE_8);
mask.drawEllipse(faceRect, new cv.Vec3(cv.GC_FGD, cv.GC_FGD, cv.GC_FGD), -1, cv.LINE_8);
const bgModel = new cv.Mat(1, 65, cv.CV_64F, 0);
const fgModel = new cv.Mat(1, 65, cv.CV_64F, 0);
const rect = new cv.Rect(0, 0, img.cols, img.rows);
img.grabCut(mask, rect, bgModel, fgModel, 5, cv.GC_INIT_WITH_MASK);
const result = new cv.Mat(img.rows, img.cols, cv.CV_8UC3);
for (let y = 0; y < mask.rows; y++) {
for (let x = 0; x < mask.cols; x++) {
const v = mask.at(y, x);
let c;
switch (v) {
case cv.GC_BGD:
c = new cv.Vec3(255, 0, 0);
break;
case cv.GC_PR_BGD:
c = new cv.Vec3(255, 127, 0);
break;
case cv.GC_FGD:
c = new cv.Vec3(0, 255, 63);
case cv.GC_PR_FGD:
c = new cv.Vec3(0, 255, 255);
break;
}
result.set(y, x, c);
}
}
await cv.imwriteAsync(path.resolve(__dirname, `mask-${index}.png`), result);
};
const run = async () => {
for (let i = 0; i < 5; i++) {
await processImage(i);
}
};
run();
```
Input

Different results:
Output from iteration 0

Output from iteration 1

Contributor guide
Research direction
Start with the isolated JavaScript script in the issue and run the repeated grabCut calls against the same input. Inspect the grabCut binding and its OpenCV interaction to determine where the run-to-run variation originates. Done means the cause is identified and repeated executions produce consistent masks, or the limitation is documented.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript
- Domain
- computer-vision
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100