the properties of the whole image by moving the partial area to be analyzed

2 次查看(过去 30 天)
I am using the regionprops function to analyze the properties of the image.
The size of the image is large, so I need to cut out parts of the image and analyze it.
I want to show the properties of the whole image by moving the partial area to be analyzed.
The image is a 5120x5120 gray image and the image is a PNG file.
It seems to be in the form of I(1:1000, 1:1000) to cut and analyze while maintaining the information on the entire pixel.
I wonder how to analyze the boundary of the window (edge of partial area).
Any good way?
  4 个评论
Walter Roberson
Walter Roberson 2021-6-3
Unfortunately png does not happen to be one of the file types that can be handled specially by blockproc(), at least not without further programming.
What kind of properties do you need to compute? Some properties are easier than others to merge together over sliding windows.
5120x5120 is only 25 megabytes, and should not be difficult to analyze all at one time, unless you are using an old 32 bit version of MATLAB ?
HJ
HJ 2021-6-3
I want to recognize the adjacent pixel as one coin(cluster) and obtain its centroid value, mean of intensity, and std.
I am using a raw file transformed into png file.
can I use it after changing the image to another extension?

请先登录,再进行评论。

采纳的回答

Walter Roberson
Walter Roberson 2021-6-3
Img = rgb2gray(imread('flamingos.jpg'));
%this assumes the image is in a variable named Img
blocksize = 256; %choose a size useful for your purposes.
rows = size(Img,1);
cols = size(Img,2);
nrblks = floor(rows/blocksize);
frblk = rows - nrblks * blocksize;
ncblks = floor(cols/blocksize);
fcblk = cols - ncblks * blocksize;
rtsz = [blocksize * ones(1,nrblks), frblk];
ctsz = [blocksize * ones(1,ncblks), fcblk];
tiles = mat2cell(Img, rtsz, ctsz, size(Img,3));
size(tiles)
ans = 1×2
4 6
%tiles is now a cell array of blocks that are blocksize x blocksize x
%number_of_channels (1 for grayscale, 3 for RGB)
stats = cell(size(tiles));
for K = 1 : numel(tiles)
thistile = tiles{K};
BW = imbinarize(thistile);
these_stats = regionprops(BW, thistile, 'centroid', 'boundingbox', 'meanintensity', 'pixelidxlist');
ncomp = size(these_stats,1);
stds = cell(ncomp,1);
for C = 1 : ncomp
stds{K} = std(double(thistile(these_stats(C).PixelIdxList)));
end
[these_stats.stds] = stds{:};
stats{K} = these_stats;
end
stats
stats = 4×6 cell array
{211×1 struct} {189×1 struct} {136×1 struct} {226×1 struct} {139×1 struct} {27×1 struct} { 67×1 struct} { 48×1 struct} { 81×1 struct} { 46×1 struct} { 67×1 struct} { 2×1 struct} {146×1 struct} {182×1 struct} {259×1 struct} { 73×1 struct} {118×1 struct} { 7×1 struct} {468×1 struct} {454×1 struct} {152×1 struct} { 82×1 struct} {140×1 struct} { 4×1 struct}
At this point, stats is a cell array, with each entry being related to a portion of the original image. Each of the entries is a struct array of statistics. The struct array will have as many elements as connected components were detected in the sub-section of the image. Information about the centroid, mean intensity, and standard deviation for each component is present.
You might want to put in an bwareafilt() call between the assignment to BW and the collection of statistics, in order to throw away small bits of unimportant noise, and only keep larger blobs. Maybe... but it isn't always a good idea.
Now, you have a problem: at each tile boundary, you might have subdivided an object between two tiles. Potentially only a small sliver ended up in one of the tiles, which is why area filtering is not always a good idea. You need to go through each component for each tile, and determine whether the bounding box touches the edge of the tile: if it does then you might have to merge components from adjacent tiles.
You cannot assume that there is only one matching component. Consider
1111|333
| 3
| 3
2222|333
where | indicates the tile boundary. As far as regionprops is concerned section 1 and 2 are disconnected from each other, but when you examine the larger context you can see that they are both parts of the same blob. And the situation can get worse:
1111|333
| 3
5|333
5|
5|444
| 4
2222|444
Tile-by-tile that appears to be 3 disconnected blobs in the first and two disconnected blobs in the second, but in the larger context really it is all one blob.
So, after you have the tiles and components, you have to splice together the blobs that are on the boundaries, figure out whether they need to be merged, remove the merged ones, and then recompute their statistics.
It isn't that this all is impossible, but it is a pain. It is considerably easier just to process the entire image at one time.
5180 x 5180 is not a big image. 26 megabytes if it is uint8. Your system should be able to handle that easily. I really recommend working on the entire image instead of trying to merge together the blobs that happen to be split by tile boundaries.
If you are having problems with extraneous small areas being picked up, and that slowing you down, then use bwareafilt() before regionprops.
  2 个评论
HJ
HJ 2021-6-3
Thank you for your kind and detailed explanation.
The use of bwareafilt() seems like a good idea.
But I was mistaken. bwareafilt() is not possible because the image is a gray image.
As you said, if I use windows, problems occur in the edge part of window.
If possible, I would like to calculate all at once, but it is currently too slow because of regionprops().
I wonder if it's too slow because there are so many clusters.
Walter Roberson
Walter Roberson 2021-6-3
minblobsize = 25;
BW = imbinarize(Img);
BW = bwareafilt(BW, [minblobsize inf]);
stats = regionprops(BW, Img, 'centroid', 'boundingbox', 'meanintensity', 'pixelidxlist');

请先登录,再进行评论。

更多回答(0 个)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by