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
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 ?
採用された回答
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)
%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
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 件のコメント
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!