@@ -117,6 +117,113 @@ function detectText(canvasIn, mode) {
117117 var ksize = new cv . Size ( 12 , 12 ) ;
118118 var element = cv . getStructuringElement ( cv . MORPH_RECT , ksize ) ;
119119 cv . cvtColor ( src , dst , cv . COLOR_RGBA2GRAY , 0 ) ;
120+ } else if ( mode . includes ( "black" ) ) {
121+ var ksize = new cv . Size ( 15 , 15 ) ;
122+ var element = cv . getStructuringElement ( cv . MORPH_RECT , ksize ) ;
123+
124+ cv . bitwise_not ( src , src ) ;
125+
126+ // Convert image to grayscale and ensure single-channel
127+ cv . cvtColor ( src , dst , cv . COLOR_RGBA2GRAY , 0 ) ;
128+ // Threshold to get white areas (255, 255, 255)
129+
130+ //get white area as mask
131+ cv . threshold ( dst , dst , 210 , 255 , cv . THRESH_BINARY ) ;
132+ // showImage(dst, mode);
133+
134+ // Create floodfill masks for each edge
135+ let combinedFloodMask = new cv . Mat (
136+ dst . rows ,
137+ dst . cols ,
138+ cv . CV_8U ,
139+ new cv . Scalar ( 0 )
140+ ) ;
141+ var combinedFloodVisited = new Set ( ) ;
142+ combinedFloodMask = customFloodFillWithoutCv (
143+ dst ,
144+ { x : 0 , y : 0 } ,
145+ combinedFloodMask ,
146+ combinedFloodVisited
147+ ) ;
148+ combinedFloodMask = customFloodFillWithoutCv (
149+ dst ,
150+ { x : dst . cols - 1 , y : 0 } ,
151+ combinedFloodMask ,
152+ combinedFloodVisited
153+ ) ;
154+ combinedFloodMask = customFloodFillWithoutCv (
155+ dst ,
156+ { x : 0 , y : dst . rows - 1 } ,
157+ combinedFloodMask ,
158+ combinedFloodVisited
159+ ) ;
160+ combinedFloodMask = customFloodFillWithoutCv (
161+ dst ,
162+ { x : dst . cols - 1 , y : dst . rows - 1 } ,
163+ combinedFloodMask ,
164+ combinedFloodVisited
165+ ) ;
166+ // showImage(combinedFloodMask, mode);
167+ // Remove mask area that exists in combinedFloodMask
168+ cv . bitwise_not ( dst , dst ) ;
169+ cv . bitwise_or ( dst , combinedFloodMask , dst ) ;
170+ cv . bitwise_not ( dst , dst ) ;
171+
172+ // cv.bitwise_not(dst, dst); // Invert the image to get black areas
173+ // cv.bitwise_not(combinedFloodMask, combinedFloodMask); // Invert the image to get black areas
174+ // cv.bitwise_and(dst, dst, dst, combinedFloodMask); // Apply the mask to the original image grep white area as mask
175+ // cv.bitwise_not(dst, dst); // Invert the image to get black areas again
176+
177+ // showImage(dst, mode);
178+
179+ // // Apply the mask to the original image grep white area as mask
180+ // let mask = new cv.Mat();
181+ // cv.bitwise_and(src, src, mask, dst);
182+ // showImage(mask, mode);
183+
184+ // make invert white area using floodfill
185+ // dst = mask.clone(); // Update dst to the masked image
186+
187+ cv . copyMakeBorder (
188+ dst ,
189+ dst ,
190+ 1 ,
191+ 1 ,
192+ 1 ,
193+ 1 ,
194+ cv . BORDER_CONSTANT ,
195+ new cv . Scalar ( 0 )
196+ ) ;
197+ // Flood fill the mask to get the white area
198+ let floodFillMask = customFloodFillWithoutCv ( dst , { x : 0 , y : 0 } ) ;
199+ cv . bitwise_not ( floodFillMask , floodFillMask ) ;
200+ floodFillMask = floodFillMask . roi (
201+ new cv . Rect ( 1 , 1 , floodFillMask . cols - 2 , floodFillMask . rows - 2 )
202+ ) ;
203+ let slicedResultMask = new cv . Mat ( ) ;
204+ cv . bitwise_and ( src , src , slicedResultMask , floodFillMask ) ;
205+
206+ // showImage(slicedResultMask, mode);
207+ // // make white background and combine with slicedResultMask
208+ cv . bitwise_not ( floodFillMask , floodFillMask ) ;
209+ cv . cvtColor ( floodFillMask , floodFillMask , cv . COLOR_GRAY2RGBA , 0 ) ;
210+ cv . bitwise_or ( slicedResultMask , floodFillMask , floodFillMask ) ;
211+ // showImage(floodFillMask, mode);
212+
213+ // Enhance color saturation
214+ let enhancedImage = new cv . Mat ( ) ;
215+ cv . cvtColor ( floodFillMask , enhancedImage , cv . COLOR_RGBA2RGB , 0 ) ;
216+ cv . convertScaleAbs ( enhancedImage , enhancedImage , 2.1 , 0 ) ; // Increase intensity
217+ cv . bitwise_not ( enhancedImage , enhancedImage ) ; // Ivert colors
218+ cv . convertScaleAbs ( enhancedImage , enhancedImage , 1.5 , 0 ) ; // Adjust intensity
219+ cv . bitwise_not ( enhancedImage , enhancedImage ) ; // Invert colors
220+ preprocessedSourceImage = enhancedImage ;
221+
222+ // showImage(preprocessedSourceImage, mode);
223+ // Update src and dst with the sliced result
224+ src = floodFillMask ;
225+ dst = preprocessedSourceImage . clone ( ) ;
226+ cv . cvtColor ( dst , dst , cv . COLOR_RGBA2GRAY , 0 ) ;
120227 } else if ( mode . includes ( "white" ) ) {
121228 var ksize = new cv . Size ( 15 , 15 ) ;
122229 var element = cv . getStructuringElement ( cv . MORPH_RECT , ksize ) ;
@@ -129,7 +236,7 @@ function detectText(canvasIn, mode) {
129236 //get white area as mask
130237 cv . threshold ( dst , dst , 230 , 255 , cv . THRESH_BINARY ) ;
131238
132- // showImage(dst, mode);
239+ // showImage(dst, mode);
133240 // Combine all masks into one
134241 let combinedFloodMask = new cv . Mat (
135242 dst . rows ,
@@ -172,13 +279,13 @@ function detectText(canvasIn, mode) {
172279 cv . bitwise_not ( dst , dst ) ;
173280
174281 // Apply the mask to the original image grep white area as mask
175- let mask = new cv . Mat ( ) ;
176- cv . bitwise_and ( src , src , mask , dst ) ;
282+ // let mask = new cv.Mat();
283+ // cv.bitwise_and(src, src, mask, dst);
177284
178285 // showImage(mask, mode);
179286
180287 // make invert white area using floodfill
181- dst = mask . clone ( ) ; // Update dst to the masked image
288+ // dst = mask.clone(); // Update dst to the masked image
182289 cv . copyMakeBorder (
183290 dst ,
184291 dst ,
@@ -211,7 +318,6 @@ function detectText(canvasIn, mode) {
211318 cv . bitwise_or ( slicedResultMask , slicedBorderMask , slicedBorderMask ) ;
212319 // showImage(slicedBorderMask, mode);
213320
214-
215321 // Enhance color saturation
216322 let enhancedImage = new cv . Mat ( ) ;
217323 cv . cvtColor ( slicedBorderMask , enhancedImage , cv . COLOR_RGBA2RGB , 0 ) ;
@@ -220,6 +326,7 @@ function detectText(canvasIn, mode) {
220326 cv . convertScaleAbs ( enhancedImage , enhancedImage , 1.5 , 0 ) ; // Adjust intensity
221327 cv . bitwise_not ( enhancedImage , enhancedImage ) ; // Invert colors
222328 preprocessedSourceImage = enhancedImage ;
329+ // showImage(preprocessedSourceImage, mode);
223330
224331 // Update src and dst with the sliced result
225332 src = slicedBorderMask ;
@@ -309,11 +416,11 @@ function detectText(canvasIn, mode) {
309416 rectCoverRatio < 0.15 ||
310417 cnt . rows < 100 ||
311418 area < 150 ||
312- ! isRightAngle ||
313- left == 0 ||
314- top == 0 ||
315- left + width == w ||
316- top + height == h
419+ ! isRightAngle
420+ // left == 0 ||
421+ // top == 0
422+ // left + width == w ||
423+ // top + height == h
317424 ) {
318425 continue ;
319426 }
@@ -434,6 +541,8 @@ function preprocessImage(canvasIn, isResize) {
434541}
435542
436543function customFloodFillWithoutCv ( image , startPoint , mask , visited ) {
544+ // console.time("customFloodFillWithoutCv");
545+
437546 let rows = image . rows ;
438547 let cols = image . cols ;
439548 var mask = mask || new cv . Mat ( rows , cols , cv . CV_8U , new cv . Scalar ( 0 ) ) ;
@@ -463,6 +572,8 @@ function customFloodFillWithoutCv(image, startPoint, mask, visited) {
463572 { x, y : y - 1 }
464573 ) ;
465574 }
575+
576+ // console.timeEnd("customFloodFillWithoutCv");
466577 return mask ;
467578}
468579
0 commit comments