Sharpening a 2D histogram and finding peaks
59 ビュー (過去 30 日間)
古いコメントを表示
Can you help me?
I have a bunch of 2D histograms that I'd like to sharpen so that I can identify some features. Here is an example image: 

Each vertical line in the image is a scan (row) in my data and I really want to operate on a per-row basis. The sharpening needs to be primarily in the vertical (value) direction.
I'm trying to identify the center (i.e., median, mode) of the upper and the lower peak for each scan. Any intermediate peaks (for example in scans 3-10) are of lesser interest. Finding the center of the the lower peak is the primary challenge.
I have attached a data file containing the data I used to generate the plot. Here is the plotting code:
function PlotHist(plotData, plotTitle)
figure;
surf(plotData); shading("flat");
xlim([0, 4096]); xticks(0 : 512 : 4096); xlabel("Laser Value");
ylim([0, size(plotData, 1)]); ylabel("Scan");
cb = colorbar; cb.Label.String = '# points';
view([90, -90])
title(plotTitle, Interpreter = 'none');
end
I've reviewed and tried a number of the Matlab answers on deblurring and sharpening, but I'm struggling to focus my results in the vertical direction.
0 件のコメント
回答 (4 件)
Steven Lord
2025 年 11 月 26 日 20:11
You're not plotting a histogram using histogram or histogram2, but did you create the data that you passed into surf using one of those two tools (or the histcounts* equivalents)?
You might want to see if you can use the islocalmax2 and islocalmin2 functions to locate your peaks and valleys and use that information to compute the center locations. The FlatSelection name-value argument may even give you what you're looking for directly from islocalmax2 or islocalmin2.
Alternately, if you want to do effectively 1-dimensional local extrema finding, try using islocalmax and islocalmin with the dim input argument.
dpb
2025 年 11 月 26 日 20:34
編集済み: dpb
2025 年 11 月 26 日 22:31
load HistSmoothed
surf(HistSmooth); shading("flat");
xlim([-inf inf]), ylim(xlim)
xlabel('X'), ylabel('Y'), zlabel('Z')
figure
surf(HistSmooth); shading("flat");
xlabel('X'), ylabel('Y'), xlabel('Z')
HMax=max(HistSmooth(:))
zlim([HMax/3 inf])
view([90 -90])
xlim([-inf inf]), ylim(xlim)
You can then try
xlim([2000 3800])
box on
or how about
hAx=gca;
hAx.XDir='reverse';
If you try to manipulate the scale in the displayed plane, it's confusing as the dickens...instead, you would need to "zoom" in the z-axis direction. The above displays just the top 2/3rds which expands the scale by 1/3rd over full scale.
However, it's not at all clear to me as to what it is you're wanting to do that makes this the chosen view although it does show that there are some paths across the 2D histogram that do have a significantly fewer number of counts in those channels.
Hmmm....maybe
figure
subplot(2,1,1)
surf(HistSmooth); shading("flat");
xlabel('X'), ylabel('Y'), zlabel('Z')
HMax=max(HistSmooth(:))
zlim([HMax/3 inf])
view([90 -90])
xlim([2000 3800])
box on
%hAx=gca;
%hAx.XDir='reverse';
subplot(2,1,2)
H1D=sum(HistSmooth,2); % marginal distribution with X
plot(H1D)
xlabel('Y'), ylabel('Z')
hAx=gca;
hAx.YDir='reverse';
?
Star Strider
2025 年 11 月 27 日 3:56
編集済み: Star Strider
2025 年 11 月 27 日 16:54
'I'm trying to identify the center (i.e., median, mode) of the upper and the lower peak for each scan.'
I am not absolutely certain what you want. I selected a series of rows that appear to correspond to one of the circled areas, and then did some simpleindexing and statistics. I plotted the data I presented to ghe functions, and then commented it out here. Uncomment those lines to plot the data. I added the standard deviation.
Try something like this --
load('HistSmoothed.mat')
% whos('HistSmoothed.mat')
rowv = (1:5)+20;
xv = 0:size(HistSmooth,1)-1;
yv = 0:size(HistSmooth,2)-1;
[Xm,Ym] = ndgrid(xv,yv);
figure
plot3(Xm(rowv,:).', Ym(rowv,:).', HistSmooth(rowv,:).')
grid
axis('padded')
idxrngv = -200:200;
for k1 = rowv %1:size(HistSmooth,1)
k1
[pks,locs] = findpeaks(HistSmooth(k1,:), MinPeakProminence=1.5)
for k2 = 1:numel(locs)
idxrng = idxrngv + locs(k2);
muest(k1,k2) = mean(HistSmooth(k1,idxrng));
stdest(k1,k2) = std(HistSmooth(k1,idxrng));
modest(k1,k2) = mode(HistSmooth(k1,idxrng));
% figure
% plot(idxrng, HistSmooth(k1,idxrng))
% % hold on
% % plot(HistSmooth(k1,idxrng))
% % hold off
% grid
% xlabel("Row Index Range")
% ylabel("Histogram Value")
% title("Column = "+k1+", Peak = "+k2)
end
end
format shortG
disp(muest)
disp(stdest)
disp(modest)
format short
.
EDIT -- (27 Nov 2025 at 16:54)
I'm not certain what you intend by 'smoothing'. One option is to filter the individual peaks, as this illustrates. Choose the cutoff frequency ('Fco') for the lowpass filter to give the result you want.
Alternatively, try something like this --
rowv = (1:5)+20;
idxrngv = -200:200;
Fco = 1/50;
Fs = 1/mean(diff(idxrngv));
for k1 = rowv %1:size(HistSmooth,1)
k1
[pks,locs] = findpeaks(HistSmooth(k1,:), MinPeakProminence=1.5)
for k2 = 1:numel(locs)
idxrng = idxrngv + locs(k2);
HistSmoothFilt(k1,:) = lowpass(HistSmooth(k1,:), Fco, Fs);
muest(k1,k2) = mean(HistSmoothFilt(k1,idxrng));
stdest(k1,k2) = std(HistSmoothFilt(k1,idxrng));
modest(k1,k2) = mode(HistSmoothFilt(k1,idxrng));
% figure
% plot(idxrng, HistSmoothFilt(k1,idxrng))
% % hold on
% % plot(HistSmooth(k1,idxrng))
% % hold off
% grid
% xlabel("Row Index Range")
% ylabel("Filtered Histogram Value")
% title("Column = "+k1+", Peak = "+k2)
end
end
format shortG
disp(muest)
disp(stdest)
disp(modest)
format short
.
1 件のコメント
dpb
2025 年 11 月 27 日 17:20
編集済み: dpb
2025 年 11 月 28 日 14:09
I was also confused by the subject of wanting to "sharpen" peaks wherein the circled areas seem to be areas of smaller magnitudes that globally don't look much like single peaks. The only idea I had would be to decimate by a factor in those areas combining counts and then recasting the total into the center of (say) 3x3 or 5x5 areas with the outer cells then being zeros. That would certainly create peaks where there aren't specifically identified ones now. Does that constitute "sharpening"? blockproc might be useful...
参考
カテゴリ
Help Center および File Exchange で Test and Measurement についてさらに検索
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!

























