a_parida
a_parida

Reputation: 636

Estimating Region covered by all sides

I need some help in estimating somekind of of morphological operations(preferably using skimage or scipy image or python in general) that can help me isolate the regions that are enclosed by all sides(see images.) The problem is the outer shell can be of varied shape and size. The enclosed regions are also of varied shapes and sizes. Examples of the image where the enclosed(by the white regions) black region needs to isolated.

By isolation I mean to get all the pixel coordinates in the enclosed black regions.

Example 1

Fill the small black region

Example 2

Fill the small black region 2

Also another caveat is that the images like this should not be filled up.

enter image description here

Upvotes: 0

Views: 152

Answers (2)

Mark Setchell
Mark Setchell

Reputation: 207818

I prefer @Juan's solution, but just for fun, here's a slightly different approach. Floodfill with white starting from the top-left corner and your fully-enclosed pixels will be all that is left over.

#!/usr/bin/env python3

import numpy as np
from skimage.segmentation import flood_fill
import cv2

im = cv2.imread('scan.png', cv2.IMREAD_GRAYSCALE)

# Fill with white from top-left
filled = flood_fill(im, (0, 0), 255)

# Save result
cv2.imwrite('DEBUG-result.png', filled)

# Get list of black pixels
blk = np.where(filled==0)
print(f'Number of fully enclosed black pixels: {len(blk[0])}')
print(blk)

So that you can see the extent of the image, I have artificially added a red border:

enter image description here

Here is the output:

Number of fully enclosed black pixels: 957
(array([364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364,
       364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364,
       364, 364, 364, 364, 364, 364, 364, 365, 365, 365, 365, 365, 365,
       365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365,
       365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365,
       365, 366, 366, 366, 366, 366, 366, 366, 366, 366, 366, 366, 366,
       366, 366, 366, 366, 366, 366, 366, 366, 366, 366, 366, 366, 366,
       366, 366, 366, 366, 366, 366, 366, 366, 367, 367, 367, 367, 367,
       367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367,
       367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367,
       367, 367, 367, 367, 367, 368, 368, 368, 368, 368, 368, 368, 368,
       368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368,
       368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368,
       368, 368, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369,
       369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369,
       369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 370,
       370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370,
       370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370,
       370, 370, 370, 370, 370, 370, 370, 370, 370, 371, 371, 371, 371,
       371, 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, 371,
       371, 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, 371,
       371, 371, 371, 371, 371, 371, 372, 372, 372, 372, 372, 372, 372,
       372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372,
       372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372,
       372, 372, 372, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373,
       373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373,
       373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 374, 374, 374,
       374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374,
       374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374,
       374, 374, 374, 374, 375, 375, 375, 375, 375, 375, 375, 375, 375,
       375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375,
       375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 376, 376,
       376, 376, 376, 376, 376, 376, 376, 376, 376, 376, 376, 376, 376,
       376, 376, 376, 376, 376, 376, 376, 376, 376, 376, 376, 376, 376,
       376, 376, 376, 376, 376, 377, 377, 377, 377, 377, 377, 377, 377,
       377, 377, 377, 377, 377, 377, 377, 377, 377, 377, 377, 377, 377,
       377, 377, 377, 377, 377, 377, 377, 377, 377, 377, 377, 377, 378,
       378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378,
       378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378,
       378, 378, 378, 378, 378, 378, 379, 379, 379, 379, 379, 379, 379,
       379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379,
       379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379,
       380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380,
       380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380,
       380, 380, 380, 380, 380, 380, 380, 381, 381, 381, 381, 381, 381,
       381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381,
       381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381,
       381, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382,
       382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382,
       382, 382, 382, 382, 382, 382, 382, 382, 383, 383, 383, 383, 383,
       383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383,
       383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383,
       383, 383, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384,
       384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384,
       384, 384, 384, 384, 384, 384, 384, 384, 384, 385, 385, 385, 385,
       385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385,
       385, 385, 385, 385, 385, 385, 385, 386, 386, 386, 386, 386, 386,
       386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386,
       386, 386, 386, 386, 386, 387, 387, 387, 387, 387, 387, 387, 387,
       387, 387, 387, 387, 387, 387, 387, 387, 387, 387, 387, 387, 387,
       387, 387, 387, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388,
       388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 389, 389,
       389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389,
       389, 389, 389, 389, 389, 389, 390, 390, 390, 390, 390, 390, 390,
       390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390,
       390, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391,
       391, 391, 391, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392,
       392, 392, 392, 392, 392, 393, 393, 393, 393, 393, 393, 393, 393,
       393, 393, 393, 393, 393, 393, 393, 394, 394, 394, 394, 394, 394,
       394, 394, 394, 394, 394, 394, 394, 394, 394, 395, 395, 395, 395,
       395, 395, 395, 395, 395, 395, 395, 395, 395, 395, 395, 396, 396,
       396, 396, 396, 396, 396, 396, 396, 397, 397, 397, 397, 397, 397,
       397, 397, 397, 398, 398, 398, 398, 398, 398, 398, 398, 398, 399,
       399, 399, 400, 400, 400, 401, 401, 401]), array([244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256,
       257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269,
       270, 271, 272, 273, 274, 275, 276, 244, 245, 246, 247, 248, 249,
       250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262,
       263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275,
       276, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255,
       256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268,
       269, 270, 271, 272, 273, 274, 275, 276, 241, 242, 243, 244, 245,
       246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258,
       259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271,
       272, 273, 274, 275, 276, 241, 242, 243, 244, 245, 246, 247, 248,
       249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261,
       262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
       275, 276, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251,
       252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264,
       265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 241,
       242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254,
       255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267,
       268, 269, 270, 271, 272, 273, 274, 275, 276, 241, 242, 243, 244,
       245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257,
       258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270,
       271, 272, 273, 274, 275, 276, 241, 242, 243, 244, 245, 246, 247,
       248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260,
       261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273,
       274, 275, 276, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250,
       251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263,
       264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 241, 242, 243,
       244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256,
       257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269,
       270, 271, 272, 273, 241, 242, 243, 244, 245, 246, 247, 248, 249,
       250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262,
       263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 241, 242,
       243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255,
       256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268,
       269, 270, 271, 272, 273, 241, 242, 243, 244, 245, 246, 247, 248,
       249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261,
       262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 241,
       242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254,
       255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267,
       268, 269, 270, 271, 272, 273, 241, 242, 243, 244, 245, 246, 247,
       248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260,
       261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273,
       241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253,
       254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266,
       267, 268, 269, 270, 271, 272, 273, 241, 242, 243, 244, 245, 246,
       247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259,
       260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272,
       273, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252,
       253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265,
       266, 267, 268, 269, 270, 271, 272, 273, 241, 242, 243, 244, 245,
       246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258,
       259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271,
       272, 273, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251,
       252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264,
       265, 266, 267, 268, 269, 270, 271, 272, 273, 253, 254, 255, 256,
       257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269,
       270, 271, 272, 273, 274, 275, 276, 253, 254, 255, 256, 257, 258,
       259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271,
       272, 273, 274, 275, 276, 253, 254, 255, 256, 257, 258, 259, 260,
       261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273,
       274, 275, 276, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265,
       266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 256, 257,
       258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270,
       271, 272, 273, 274, 275, 276, 256, 257, 258, 259, 260, 261, 262,
       263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275,
       276, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270,
       271, 272, 273, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268,
       269, 270, 271, 272, 273, 259, 260, 261, 262, 263, 264, 265, 266,
       267, 268, 269, 270, 271, 272, 273, 259, 260, 261, 262, 263, 264,
       265, 266, 267, 268, 269, 270, 271, 272, 273, 259, 260, 261, 262,
       263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 262, 263,
       264, 265, 266, 267, 268, 269, 270, 262, 263, 264, 265, 266, 267,
       268, 269, 270, 262, 263, 264, 265, 266, 267, 268, 269, 270, 265,
       266, 267, 265, 266, 267, 265, 266, 267]))

Hopefully you can see from the first element of each array that the first black pixel is at 364,244

Note that, if there is the possibility that the scan would touch the edge of the image, the flood-fill will fail to "flow" all the way around the edges. In this case, you can simply add a 1-pixel wide black border all the way around the edge for the floodfill to flow around... and remove it afterwards.

Upvotes: 1

Juan
Juan

Reputation: 5768

Use scipy.ndimage.binary_fill_holes

from scipy import ndimage as ndi

filled = ndi.binary_fill_holes(image)
holes = filled - image  # or np.logical_xor(filled, image)

Upvotes: 3

Related Questions