How to draw contours around the OUTSIDE of pixels?

19 views (last 30 days)
Given a matrix, I want to plot the values by color (e.g., pcolor or image), then overlay a contour. The problem is that the contours want to be drawn through the pixel centers, whereas what I want is for them to be around the pixel edges. Here is some example code:
% Generate data
mydata = magic(10) ;
myoverlay = mydata>50 ;
% Regular contour lines
figure ;
image(mydata) ;
colorbar
hold on
[c2,h2] = contour(double(myoverlay),[1,1]) ;
hold off
% Hatched using hatchfill2
% https://www.mathworks.com/matlabcentral/fileexchange/53593-hatchfill2
figure ;
image(mydata) ;
colorbar
hold on
[c2,h2] = contourf(double(myoverlay),[1,1]) ;
hold off
set(h2,'fill','off');
set(h2,'linestyle','none','Tag','HatchingRegion');
ax1 = gca;
hp = findobj(ax1,'Tag','HatchingRegion');
hh = hatchfill2(hp,'single','LineWidth',0.1,'Fill','off',...
'HatchDensity',200);
% Just the overlay, for reference
figure;
image(myoverlay) ;
In Fig. 1, I'm not sure why all the points for each contour aren't connected, but that's resolved anyway when using hatchfill2 (Fig. 2). Comparing to Fig. 3 (not sure why the colors are like that), you can see my issues in Fig. 2. First, of course, the contours are drawn through the pixel centers instead of the pixel edges. This has the side effect of 1-dimensional areas—the point at (1,8) and the line at (10,6:10)—disappearing.
How do I get this to do what I want? I'm using r2016a, and if it helps, I have the Image Processing toolbox installed. Also, in my real code I'm plotting geographic maps, so Mapping Toolbox solutions would also work, and might even be preferable so I could also overlay a country map.
This question looks like it might be useful, but I'm not sure how to implement it.

Answers (1)

Kevin Holly
Kevin Holly on 21 Apr 2018
Edited: Kevin Holly on 21 Apr 2018

I obtained the bwperimtrace function from:

https://www.mathworks.com/matlabcentral/fileexchange/49551-trace-perimeter-of-binary-image-with-line-segments--bwperimtrace-

I changed lines 32 and 33 of the bwperimtrace function from:

xpix = xlims(1):dx:xlims(2);
ypix = ylims(1):dy:ylims(2);

to

xpix = xlims(1):dx:xlims(end);
ypix = ylims(1):dy:ylims(end);

Then I ran the following:

% Generate data
mydata = magic(10) ;
myoverlay = mydata>50 ;
%Generate trace around pixels
cellout=bwperimtrace((myoverlay-1)*-1)
figure;
for i = 1:1:length(cellout)
plot(cellout{i}(:,1),cellout{i}(:,2))
hold on
end

Community Treasure Hunt

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

Start Hunting!