cy_f
January 25, 2024, 7:06am
1
I want to use the floodFill to fill background to the white
So i select a point on background and then i try to change the loDiff and hiDiff, I used the same value in javascript and c#, but the c# has make most background to white but js is only make a little And i hava look arount at the pixel Data in js ,but i have see that the most pixel date is same to seed data but the do not flood it, and this is my code
Is there anyone can help?
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Hello OpenCV.js</title>
<script
async
src="opencv.js"
onload="onOpenCvReady();"
type="text/javascript"
></script>
</head>
<body>
<h2>Hello OpenCV.js</h2>
<p id="status">OpenCV.js is loading...</p>
<div>
<button onclick="btnFloodclick()"> floodFill </button>
<canvas id="canvasOutput" style="width: 200px;height: 200px;"></canvas>
</div>
<img src="./0.png" id="my_img" />
<script type="text/javascript">
function onOpenCvReady() {
document.getElementById("status").innerHTML = "OpenCV.js is ready.";
}
function btnFloodclick(){
let canvas = document.getElementById("my_img");
let mat = cv.imread(canvas);
let canvasCoords={x:492,y:404};
cv.cvtColor(mat,mat,cv.COLOR_RGBA2GRAY);
const mask = new cv.Mat(mat.rows + 2, mat.cols + 2, cv.CV_8U, new cv.Scalar(0));
let p = new cv.Point(parseInt(canvasCoords.x), parseInt(canvasCoords.y));
let sc = new cv.Scalar.all(255);
// y-->row(height) x-->col(width)
let src = mat;
for(let j = p.x-5; j <= p.x+5; j++) {
let x = "";
for(let i = p.y-5; i <= p.y+5; i++){
let R = src.data[i * src.cols * src.channels() + j * src.channels()];
if(j == p.x && i == p.y){
x += "!";
}
x += "[" + R + "]" + " ";
}
console.log(x);
}
cv.floodFill(mat, mask, p, sc, cv.Scalar.all(0), cv.Scalar.all(6));
console.log("==============================");
src = mask;
for(let j = p.x-5; j <= p.x+5; j++) {
let x = "";
for(let i = p.y-5; i <= p.y+5; i++) {
let R = src.data[i * src.cols * src.channels() + j * src.channels()];
if(j-1 == p.x && i-1 == p.y){
x += "!";
}
x += "[" + R + "]" + " ";
}
console.log(x);
}
cv.imshow('canvasOutput', mat);
mat.delete();
mask.delete();
}
</script>
</body>
</html>
There are value arond the seed point in src image and mask image
[7] [7] [7] [8] [9] [8] [7] [6] [4] [4] [4]
[8] [8] [8] [9] [8] [7] [6] [5] [4] [4] [4]
[9] [9] [9] [9] [8] [6] [5] [4] [4] [4] [4]
[9] [9] [9] [8] [7] [7] [6] [4] [4] [4] [5]
[8] [8] [7] [7] [7] [7] [7] [4] [4] [5] [6]
[6] [5] [5] [5] [6] ![8] [8] [5] [4] [7] [7]
[5] [5] [5] [4] [5] [8] [7] [5] [5] [7] [8]
[5] [6] [6] [3] [3] [5] [6] [4] [5] [7] [8]
[7] [7] [6] [3] [3] [4] [5] [4] [5] [7] [8]
[8] [8] [6] [4] [4] [5] [5] [5] [6] [8] [9]
[8] [7] [6] [6] [6] [6] [6] [5] [6] [9] [9]
==============================
[0] [0] [0] [0] [0] [0] [0] [0] [0] [1] [1]
[0] [0] [0] [0] [0] [0] [0] [0] [0] [1] [1]
[0] [0] [0] [0] [0] [0] [0] [0] [0] [1] [1]
[0] [0] [0] [0] [0] [0] [1] [1] [1] [1] [1]
[0] [0] [0] [0] [0] [1] [1] [1] [1] [1] [1]
[0] [0] [0] [1] [1] [1] [1] [1] [1] [1] [0]
[0] [0] [1] [1] [1] [1] ![1] [1] [1] [1] [0]
[0] [1] [1] [1] [1] [1] [1] [1] [1] [1] [0]
[0] [1] [0] [0] [1] [1] [1] [1] [1] [1] [0]
[0] [0] [0] [0] [1] [1] [1] [1] [1] [1] [0]
[0] [0] [0] [0] [1] [1] [1] [1] [1] [0] [0]
cy_f
January 26, 2024, 8:00am
2
When i read the code i hava a question that is should we use abs for calc the diff?
Now it is https://github.com/opencv/opencv/blob/69772b02602bb0ada7358471ef21dc52636c022b/modules/imgproc/src/floodfill.cpp#L224
for example : one byte one channel
/****************************************************************************************\
* Gradient Floodfill *
\****************************************************************************************/
struct Diff8uC1
{
Diff8uC1(uchar _lo, uchar _up) : lo(_lo), interval(_lo + _up) {}
bool operator()(const uchar* a, const uchar* b) const
{ return (unsigned)(a[0] - b[0] + lo) <= interval; }
unsigned lo, interval;
};
but when it is compare with 2 and 4, it will be a big num for them , but it should not be that
cy_f
January 26, 2024, 8:08am
3
I also try this code in js
let mat = cv.imread(canvas);
let canvasCoords={x:492,y:461};
cv.cvtColor(mat,mat,cv.COLOR_RGBA2GRAY);
//#region try it in bfs
let lodiff = cv.Scalar.all(0),updiff = cv.Scalar.all(6);
let matChan = mat.channels();
let seedPointPixelVal = mat.data[p.y * mat.cols * matChan + p.x * matChan];
console.log(seedPointPixelVal);
//console.log(mat.rows + " " + mat.cols);
let set = new Set();
let que = [p];
let posi = [[1,0],[-1,0],[0,1],[0,-1]]
while(que.length!=0) {
let sz = que.length;
for(let i = 0; i < sz; i++) {
let cur = que.pop();
set.add(JSON.stringify(cur));
mat.data[cur.y * mat.cols * matChan + cur.x * matChan] = 255
// 分别计算4个相邻的角
for(let j = 0; j < posi.length; j++) {
nxt = {x:cur.x+posi[j][0], y:cur.y+posi[j][1]};
if(nxt.x < mat.cols && nxt.x >= 0
&& nxt.y < mat.rows && nxt.y >= 0)
{
if(set.has(JSON.stringify(nxt)))
{
continue;
}
if(Math.abs(mat.data[nxt.y * mat.cols * matChan + nxt.x * matChan] - seedPointPixelVal) + lodiff[0] < updiff[0])
que.push(nxt);
else{}
//console.warn("===")
}
else{
//console.warn("****" + nxt.x + " " + nxt.y);
}
}
}
}
cv.imshow('test', mat);
mat.delete();
mask.delete();
return;
//#endregion
and it works well, but to give same parm to floodFill, it only mask a little point?
is there any one konw why that happen and how i can do?
cy_f
January 26, 2024, 9:18am
4
there is all the code in html and my image is here
The opencv.js is build from opencv
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Hello OpenCV.js</title>
<!-- 使用js版的opencv -->
<script
async
src="opencv.js"
onload="onOpenCvReady();"
type="text/javascript"
></script>
</head>
<body>
<h2>Hello OpenCV.js</h2>
<p id="status">OpenCV.js is loading...</p>
<div>
<button onclick="btnFloodclick()"> flood </button>
<button onclick="btnBfsFloodClick()">flood bfs</button>
<canvas id="canvasOutput" style="width: 200px;height: 200px;"></canvas>
<canvas id="canvasOutput2" style="width: 200px;height: 200px;"></canvas>
</div>
<img src="./0.png" id="my_img" />
<script type="text/javascript">
function onOpenCvReady() {
document.getElementById("status").innerHTML = "OpenCV.js is ready.";
lodiff = cv.Scalar.all(0),updiff = cv.Scalar.all(60);
btnBfsFloodClick();
btnFloodclick();
}
let lodiff,updiff;
function btnBfsFloodClick(){
let canvas = document.getElementById("my_img");
let mat = cv.imread(canvas);
let canvasCoords={x:492,y:461+1};
let p = new cv.Point(parseInt(canvasCoords.x), parseInt(canvasCoords.y));
let sc = new cv.Scalar.all(255);
cv.cvtColor(mat,mat,cv.COLOR_RGBA2GRAY);
//#region try it in bfs
let matChan = mat.channels();
let seedPointPixelVal = mat.data[p.y * mat.cols * matChan + p.x * matChan];
console.log(seedPointPixelVal);
//console.log(mat.rows + " " + mat.cols);
let set = new Set();
let que = [p];
let posi = [[1,0],[-1,0],[0,1],[0,-1]]
while(que.length!=0) {
let sz = que.length;
for(let i = 0; i < sz; i++) {
let cur = que.pop();
set.add(JSON.stringify(cur));
mat.data[cur.y * mat.cols * matChan + cur.x * matChan] = 255
// 分别计算4个相邻的角
for(let j = 0; j < posi.length; j++) {
nxt = {x:cur.x+posi[j][0], y:cur.y+posi[j][1]};
if(nxt.x < mat.cols && nxt.x >= 0
&& nxt.y < mat.rows && nxt.y >= 0)
{
if(set.has(JSON.stringify(nxt)))
{
continue;
}
if(Math.abs(mat.data[nxt.y * mat.cols * matChan + nxt.x * matChan] - seedPointPixelVal) + lodiff[0] < updiff[0] + lodiff[0])
que.push(nxt);
else{}
//console.warn("===")
}
else{
//console.warn("****" + nxt.x + " " + nxt.y);
}
}
}
}
cv.imshow('canvasOutput2', mat);
mat.delete();
//mask.delete();
return;
//#endregion
}
function btnFloodclick(){
let canvas = document.getElementById("my_img");
let mat = cv.imread(canvas);
let canvasCoords={x:492,y:461+1};
let p = new cv.Point(parseInt(canvasCoords.x), parseInt(canvasCoords.y));
let sc = new cv.Scalar.all(255);
cv.cvtColor(mat,mat,cv.COLOR_RGBA2GRAY);
const mask = new cv.Mat(mat.rows + 2, mat.cols + 2, cv.CV_8U, cv.Scalar.all(0));
// 看看当前p范围内的像素大小
// y-->row(height) x-->col(width)
let src = mat;
for(let i = p.y-5; i <= p.y+5; i++){
let x = "";
for(let j = p.x-5; j <= p.x+5; j++) {
let R = src.data[i * src.cols * src.channels() + j * src.channels()];
if(j == p.x && i == p.y){
x += "!";
}
x += "[" + R + "]" + " ";
}
console.log(x);
}
console.log("------------");
console.log(mask.data);
console.log("------------");
cv.floodFill(mat, mask, p, sc, lodiff, updiff);
console.log("==============================");
src = mask;
for(let i = p.y-5; i <= p.y+5; i++) {
let x = "";
for(let j = p.x-5; j <= p.x+5; j++) {
let R = src.data[i * src.cols * src.channels() + j * src.channels()];
if(j-1 == p.x && i-1 == p.y){
x += "!";
}
x += "[" + R + "]" + " ";
}
console.log(x);
}
cv.imshow('canvasOutput', mat);
console.log("------------");
console.log(mask.data);
mat.delete();
mask.delete();
}
</script>
</body>
</html>