{"id":3317,"date":"2019-06-13T12:14:31","date_gmt":"2019-06-13T16:14:31","guid":{"rendered":"https:\/\/blogs.mathworks.com\/steve\/?p=3317"},"modified":"2019-11-01T22:44:12","modified_gmt":"2019-11-02T02:44:12","slug":"pixelgrid","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/steve\/2019\/06\/13\/pixelgrid\/","title":{"rendered":"pixelgrid"},"content":{"rendered":"<div class=\"content\"><!--introduction--><!--\/introduction--><h3>Contents<\/h3><div><ul><li><a href=\"#19c28960-7001-4a2c-86c9-b95305448545\">Introduction<\/a><\/li><li><a href=\"#0a4cac31-44fa-407d-9df9-1973e90353d4\">Find the image object<\/a><\/li><li><a href=\"#0b3faf4d-05d2-4f22-a34a-b9a4c55ceb3e\">Get the spatial coordinates for drawing the outline<\/a><\/li><li><a href=\"#0c4204c7-f8c8-49b8-8d3a-12ef6606c9f2\">Construct the x- and y-vectors<\/a><\/li><li><a href=\"#e510d9eb-ae42-4feb-830d-f1d7ee61b784\">Draw the lines<\/a><\/li><\/ul><\/div><h4>Introduction<a name=\"19c28960-7001-4a2c-86c9-b95305448545\"><\/a><\/h4><p>Some years ago, I blogged about how to overlay a pixel grid on an image, so that you could clearly see pixel boundaries on a zoomed-in view of the image. Something like this:<\/p><p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/steve\/files\/pixel-grid-example.png\" alt=\"\"> <\/p><p>I intended to submit the code to the <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/\">File Exchange<\/a>, but I got sidetracked and never did that. But a reader asked me about it recently, so I found the code and finally <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/71622-pixel-grid\">submitted it<\/a>.<\/p><p>Here's the code for making the tiny image (only 4x7) shown above.<\/p><pre class=\"codeinput\">bw = [<span class=\"keyword\">...<\/span>\r\n    0 0 0 1 0 0 0\r\n    0 0 1 0 1 0 0\r\n    0 1 0 0 0 1 0\r\n    1 1 1 1 1 1 1 ]\r\n<\/pre><pre class=\"codeoutput\">\r\nbw =\r\n\r\n     0     0     0     1     0     0     0\r\n     0     0     1     0     1     0     0\r\n     0     1     0     0     0     1     0\r\n     1     1     1     1     1     1     1\r\n\r\n<\/pre><p>And here's what it looks like when you display it using <tt>imshow<\/tt>.<\/p><pre class=\"codeinput\">imshow(bw,<span class=\"string\">'InitialMagnification'<\/span>,<span class=\"string\">'fit'<\/span>)\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/steve\/files\/pixel_grid_2019_01.png\" alt=\"\"> <p>It's hard to see the individual pixels, and there's a whole row of white pixels at the bottom of the image that have disappeared into the background of the page. It would be nice to have a subtle but visible outline around each pixel. Here's some basic code that draws some gray lines on top of the lines.<\/p><pre class=\"codeinput\">hold <span class=\"string\">on<\/span>\r\n<span class=\"keyword\">for<\/span> x = 0.5:1:7.5\r\n    xx = [x x];\r\n    yy = [0.5 4.5];\r\n    plot(xx,yy,<span class=\"string\">'Color'<\/span>,[0.6 0.6 0.6]);\r\n<span class=\"keyword\">end<\/span>\r\n\r\n<span class=\"keyword\">for<\/span> y = 0.5:1:4.5\r\n    xx = [0.5 7.5];\r\n    yy = [y y];\r\n    plot(xx,yy,<span class=\"string\">'Color'<\/span>,[0.6 0.6 0.6]);\r\n<span class=\"keyword\">end<\/span>\r\nhold <span class=\"string\">off<\/span>\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/steve\/files\/pixel_grid_2019_02.png\" alt=\"\"> <p>That works for the image above, but it won't work in general. No matter what color we choose for the pixel outlines, there is always the possibility that some image pixels will be the same or close to that color. For example:<\/p><pre class=\"codeinput\">f = bw;\r\nf(f ~= 0) = 0.6;\r\nimshow(f,<span class=\"string\">'InitialMagnification'<\/span>,<span class=\"string\">'fit'<\/span>)\r\n\r\nhold <span class=\"string\">on<\/span>\r\n<span class=\"keyword\">for<\/span> x = 0.5:1:7.5\r\n    xx = [x x];\r\n    yy = [0.5 4.5];\r\n    plot(xx,yy,<span class=\"string\">'Color'<\/span>,[0.6 0.6 0.6]);\r\n<span class=\"keyword\">end<\/span>\r\n\r\n<span class=\"keyword\">for<\/span> y = 0.5:1:4.5\r\n    xx = [0.5 7.5];\r\n    yy = [y y];\r\n    plot(xx,yy,<span class=\"string\">'Color'<\/span>,[0.6 0.6 0.6]);\r\n<span class=\"keyword\">end<\/span>\r\nhold <span class=\"string\">off<\/span>\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/steve\/files\/pixel_grid_2019_03.png\" alt=\"\"> <p>To solve this problem, I take the approach of drawing two different lines, in the same locations, with different thicknesses and contrasting colors. That way, the outline is guaranteed to always be visible, regardless of the underlying image pixel colors.<\/p><p>Here are the basic steps followed by my <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/71622-pixel-grid\/\"><tt>pixelgrid<\/tt> function<\/a> on the File Exchange:<\/p><div><ol><li>Find the image object.<\/li><li>Get the spatial coordinates for the left, right, top, and bottom of every row and column of image pixels.<\/li><li>Construct a single x-vector and a single y-vector that can be used to draw the entire outline.<\/li><li>Draw the outline using two contrasting lines.<\/li><\/ol><\/div><p>Here's a new figure with an image displayed so that I can show how each step works.<\/p><pre class=\"codeinput\">figure\r\nimshow(f,<span class=\"string\">'InitialMagnification'<\/span>,<span class=\"string\">'fit'<\/span>)\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/steve\/files\/pixel_grid_2019_04.png\" alt=\"\"> <h4>Find the image object<a name=\"0a4cac31-44fa-407d-9df9-1973e90353d4\"><\/a><\/h4><p>I want to be able to call <tt>pixelgrid<\/tt> with no arguments and just it find everything it needs automatically.)<\/p><pre class=\"codeinput\">h_im = findobj(gca,<span class=\"string\">'type'<\/span>,<span class=\"string\">'image'<\/span>);\r\n<\/pre><h4>Get the spatial coordinates for drawing the outline<a name=\"0b3faf4d-05d2-4f22-a34a-b9a4c55ceb3e\"><\/a><\/h4><p>The image object has this information. It can tell us the number of rows and columns in the image, as well as the spatial coordinates for the left, right, top, and bottom edges of the image.<\/p><pre class=\"codeinput\">[M,N,~] = size(h_im.CData);\r\nxdata = h_im.XData;\r\nydata = h_im.YData;\r\n\r\npixel_height = (ydata(2) - ydata(1)) \/ (M-1)\r\n<\/pre><pre class=\"codeoutput\">\r\npixel_height =\r\n\r\n     1\r\n\r\n<\/pre><pre class=\"codeinput\">pixel_width = (xdata(2) - xdata(1)) \/ (N-1)\r\n<\/pre><pre class=\"codeoutput\">\r\npixel_width =\r\n\r\n     1\r\n\r\n<\/pre><p>(Note: <tt>pixelgrid<\/tt> contains additional code to handle the special case where the image has only one row or column.)<\/p><h4>Construct the x- and y-vectors<a name=\"0c4204c7-f8c8-49b8-8d3a-12ef6606c9f2\"><\/a><\/h4><p>Pay attention to the need to draw the outlines <b>in between<\/b> the pixel centers.<\/p><pre class=\"codeinput\">y_top = ydata(1) - (pixel_height\/2);\r\ny_bottom = ydata(2) + (pixel_height\/2);\r\ny = linspace(y_top, y_bottom, M+1);\r\n\r\nx_left = xdata(1) - (pixel_width\/2);\r\nx_right = xdata(2) + (pixel_width\/2);\r\nx = linspace(x_left, x_right, N+1);\r\n<\/pre><p><tt>xv1<\/tt> and <tt>yv1<\/tt> are used to draw vertical line segments. The coordinates of each vertical segment are separated by NaNs.<\/p><pre class=\"codeinput\">xv1 = NaN(1,3*numel(x));\r\nxv1(1:3:end) = x;\r\nxv1(2:3:end) = x;\r\nyv1 = repmat([y(1) y(end) NaN], 1, numel(x));\r\n<\/pre><p>Similarly, <tt>xv2<\/tt> and <tt>yv2<\/tt> are used to draw all the horizontal line segments.<\/p><pre class=\"codeinput\">yv2 = NaN(1,3*numel(y));\r\nyv2(1:3:end) = y;\r\nyv2(2:3:end) = y;\r\nxv2 = repmat([x(1) x(end) NaN], 1, numel(y));\r\n\r\n<span class=\"comment\">% Put all the vertices together so that they can be drawn with a single<\/span>\r\n<span class=\"comment\">% call to line().<\/span>\r\nxv = [xv1(:) ; xv2(:)];\r\nyv = [yv1(:) ; yv2(:)];\r\n<\/pre><h4>Draw the lines<a name=\"e510d9eb-ae42-4feb-830d-f1d7ee61b784\"><\/a><\/h4><p>Use contrasting colors.<\/p><pre class=\"codeinput\">dark_gray = [0.3 0.3 0.3];\r\nlight_gray = [0.8 0.8 0.8];\r\n<\/pre><p>Draw the underneath line a little bit thicker.<\/p><pre class=\"codeinput\">bottom_line_width = 2;\r\ntop_line_width = 1;\r\n<\/pre><p>When creating the lines, set the <tt>AlignVertexCenters<\/tt> property to <tt>'on'<\/tt>. This aligns the line positions with pixels on the screen so that the graphics anti-aliased rendering doesn't make them appear to change brightness.<\/p><pre class=\"codeinput\">h_ax = ancestor(h_im,<span class=\"string\">'axes'<\/span>);\r\n\r\nline(<span class=\"keyword\">...<\/span>\r\n    <span class=\"string\">'Parent'<\/span>,h_ax,<span class=\"keyword\">...<\/span>\r\n    <span class=\"string\">'XData'<\/span>,xv,<span class=\"keyword\">...<\/span>\r\n    <span class=\"string\">'YData'<\/span>,yv,<span class=\"keyword\">...<\/span>\r\n    <span class=\"string\">'LineWidth'<\/span>,bottom_line_width,<span class=\"keyword\">...<\/span>\r\n    <span class=\"string\">'Color'<\/span>,dark_gray,<span class=\"keyword\">...<\/span>\r\n    <span class=\"string\">'LineStyle'<\/span>,<span class=\"string\">'-'<\/span>,<span class=\"keyword\">...<\/span>\r\n    <span class=\"string\">'AlignVertexCenters'<\/span>,<span class=\"string\">'on'<\/span>);\r\nline(<span class=\"keyword\">...<\/span>\r\n    <span class=\"string\">'Parent'<\/span>,h_ax,<span class=\"keyword\">...<\/span>\r\n    <span class=\"string\">'XData'<\/span>,xv,<span class=\"keyword\">...<\/span>\r\n    <span class=\"string\">'YData'<\/span>,yv,<span class=\"keyword\">...<\/span>\r\n    <span class=\"string\">'LineWidth'<\/span>,top_line_width,<span class=\"keyword\">...<\/span>\r\n    <span class=\"string\">'Color'<\/span>,light_gray,<span class=\"keyword\">...<\/span>\r\n    <span class=\"string\">'LineStyle'<\/span>,<span class=\"string\">'-'<\/span>,<span class=\"keyword\">...<\/span>\r\n    <span class=\"string\">'AlignVertexCenters'<\/span>,<span class=\"string\">'on'<\/span>);\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/steve\/files\/pixel_grid_2019_05.png\" alt=\"\"> <p>Give <tt>pixelgrid<\/tt> a try. You can find it on the <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/71622-pixel-grid\/\">File Exchange<\/a>.<\/p><script language=\"JavaScript\"> <!-- \r\n    function grabCode_4b4573f0bec7462bb584a41b127e6a5c() {\r\n        \/\/ Remember the title so we can use it in the new page\r\n        title = document.title;\r\n\r\n        \/\/ Break up these strings so that their presence\r\n        \/\/ in the Javascript doesn't mess up the search for\r\n        \/\/ the MATLAB code.\r\n        t1='4b4573f0bec7462bb584a41b127e6a5c ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' 4b4573f0bec7462bb584a41b127e6a5c';\r\n    \r\n        b=document.getElementsByTagName('body')[0];\r\n        i1=b.innerHTML.indexOf(t1)+t1.length;\r\n        i2=b.innerHTML.indexOf(t2);\r\n \r\n        code_string = b.innerHTML.substring(i1, i2);\r\n        code_string = code_string.replace(\/REPLACE_WITH_DASH_DASH\/g,'--');\r\n\r\n        \/\/ Use \/x3C\/g instead of the less-than character to avoid errors \r\n        \/\/ in the XML parser.\r\n        \/\/ Use '\\x26#60;' instead of '<' so that the XML parser\r\n        \/\/ doesn't go ahead and substitute the less-than character. \r\n        code_string = code_string.replace(\/\\x3C\/g, '\\x26#60;');\r\n\r\n        copyright = 'Copyright 2019 The MathWorks, Inc.';\r\n\r\n        w = window.open();\r\n        d = w.document;\r\n        d.write('<pre>\\n');\r\n        d.write(code_string);\r\n\r\n        \/\/ Add copyright line at the bottom if specified.\r\n        if (copyright.length > 0) {\r\n            d.writeln('');\r\n            d.writeln('%%');\r\n            if (copyright.length > 0) {\r\n                d.writeln('% _' + copyright + '_');\r\n            }\r\n        }\r\n\r\n        d.write('<\/pre>\\n');\r\n\r\n        d.title = title + ' (MATLAB code)';\r\n        d.close();\r\n    }   \r\n     --> <\/script><p style=\"text-align: right; font-size: xx-small; font-weight:lighter;   font-style: italic; color: gray\"><br><a href=\"javascript:grabCode_4b4573f0bec7462bb584a41b127e6a5c()\"><span style=\"font-size: x-small;        font-style: italic;\">Get \r\n      the MATLAB code <noscript>(requires JavaScript)<\/noscript><\/span><\/a><br><br>\r\n      Published with MATLAB&reg; R2019a<br><\/p><\/div><!--\r\n4b4573f0bec7462bb584a41b127e6a5c ##### SOURCE BEGIN #####\r\n%%\r\n\r\n%% Introduction\r\n% Some years ago, I blogged about how to overlay a pixel grid on an image,\r\n% so that you could clearly see pixel boundaries on a zoomed-in view of the\r\n% image. Something like this:\r\n%\r\n% <<https:\/\/blogs.mathworks.com\/steve\/files\/pixel-grid-example.png>>\r\n%\r\n% I intended to submit the code to the\r\n% <https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/ File Exchange>,\r\n% but I got sidetracked and never did that. But a reader asked me about it\r\n% recently, so I found the code and finally\r\n% <https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/71622-pixel-grid\r\n% submitted it>.\r\n%\r\n% Here's the code for making the tiny image (only 4x7) shown above.\r\n\r\nbw = [...\r\n    0 0 0 1 0 0 0\r\n    0 0 1 0 1 0 0\r\n    0 1 0 0 0 1 0\r\n    1 1 1 1 1 1 1 ]\r\n\r\n%%\r\n% And here's what it looks like when you display it using |imshow|.\r\n\r\nimshow(bw,'InitialMagnification','fit')\r\n\r\n%%\r\n% It's hard to see the individual pixels, and there's a whole row of white\r\n% pixels at the bottom of the image that have disappeared into the\r\n% background of the page. It would be nice to have a subtle but visible\r\n% outline around each pixel. Here's some basic code that draws some\r\n% gray lines on top of the lines.\r\n\r\nhold on\r\nfor x = 0.5:1:7.5\r\n    xx = [x x];\r\n    yy = [0.5 4.5];\r\n    plot(xx,yy,'Color',[0.6 0.6 0.6]);\r\nend\r\n\r\nfor y = 0.5:1:4.5\r\n    xx = [0.5 7.5];\r\n    yy = [y y];\r\n    plot(xx,yy,'Color',[0.6 0.6 0.6]);\r\nend\r\nhold off\r\n\r\n%%\r\n% That works for the image above, but it won't work in general. No matter\r\n% what color we choose for the pixel outlines, there is always the\r\n% possibility that some image pixels will be the same or close to that\r\n% color. For example:\r\n\r\nf = bw;\r\nf(f ~= 0) = 0.6;\r\nimshow(f,'InitialMagnification','fit')\r\n\r\nhold on\r\nfor x = 0.5:1:7.5\r\n    xx = [x x];\r\n    yy = [0.5 4.5];\r\n    plot(xx,yy,'Color',[0.6 0.6 0.6]);\r\nend\r\n\r\nfor y = 0.5:1:4.5\r\n    xx = [0.5 7.5];\r\n    yy = [y y];\r\n    plot(xx,yy,'Color',[0.6 0.6 0.6]);\r\nend\r\nhold off\r\n\r\n%%\r\n% To solve this problem, I take the approach of drawing two different\r\n% lines, in the same locations, with different thicknesses and contrasting\r\n% colors. That way, the outline is guaranteed to always be visible,\r\n% regardless of the underlying image pixel colors.\r\n%\r\n% Here are the basic steps followed by my\r\n% <https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/71622-pixel-grid\/\r\n% |pixelgrid| function> on the File Exchange:\r\n%\r\n% # Find the image object. \r\n% # Get the spatial coordinates for the left, right, top, and bottom of\r\n% every row and column of image pixels.\r\n% # Construct a single x-vector and a single y-vector that can be used to\r\n% draw the entire outline.\r\n% # Draw the outline using two contrasting lines.\r\n%\r\n% Here's a new figure with an image displayed so that I can show how each\r\n% step works.\r\n\r\nfigure\r\nimshow(f,'InitialMagnification','fit')\r\n\r\n%% Find the image object\r\n% I want to be able to call |pixelgrid| with no arguments and just it find\r\n% everything it needs automatically.) \r\n\r\nh_im = findobj(gca,'type','image');\r\n\r\n%% Get the spatial coordinates for drawing the outline\r\n% The image object has this information. It can tell us the number of rows\r\n% and columns in the image, as well as the spatial coordinates for the\r\n% left, right, top, and bottom edges of the image.\r\n\r\n[M,N,~] = size(h_im.CData);\r\nxdata = h_im.XData;\r\nydata = h_im.YData;\r\n\r\npixel_height = (ydata(2) - ydata(1)) \/ (M-1)\r\n\r\n%%\r\n\r\npixel_width = (xdata(2) - xdata(1)) \/ (N-1)\r\n\r\n%%\r\n% (Note: |pixelgrid| contains additional code to handle the special case\r\n% where the image has only one row or column.)\r\n\r\n%% Construct the x- and y-vectors\r\n% Pay attention to the need to draw the outlines *in between* the pixel\r\n% centers.\r\n\r\ny_top = ydata(1) - (pixel_height\/2);\r\ny_bottom = ydata(2) + (pixel_height\/2);\r\ny = linspace(y_top, y_bottom, M+1);\r\n\r\nx_left = xdata(1) - (pixel_width\/2);\r\nx_right = xdata(2) + (pixel_width\/2);\r\nx = linspace(x_left, x_right, N+1);\r\n\r\n%%\r\n% |xv1| and |yv1| are used to draw vertical line segments. The coordinates\r\n% of each vertical segment are separated by NaNs.\r\nxv1 = NaN(1,3*numel(x));\r\nxv1(1:3:end) = x;\r\nxv1(2:3:end) = x;\r\nyv1 = repmat([y(1) y(end) NaN], 1, numel(x));\r\n\r\n%%\r\n% Similarly, |xv2| and |yv2| are used to draw all the horizontal line\r\n% segments.\r\nyv2 = NaN(1,3*numel(y));\r\nyv2(1:3:end) = y;\r\nyv2(2:3:end) = y;\r\nxv2 = repmat([x(1) x(end) NaN], 1, numel(y));\r\n\r\n% Put all the vertices together so that they can be drawn with a single\r\n% call to line().\r\nxv = [xv1(:) ; xv2(:)];\r\nyv = [yv1(:) ; yv2(:)];\r\n\r\n%% Draw the lines\r\n% Use contrasting colors.\r\n\r\ndark_gray = [0.3 0.3 0.3];\r\nlight_gray = [0.8 0.8 0.8];\r\n\r\n%%\r\n% Draw the underneath line a little bit thicker.\r\n\r\nbottom_line_width = 2;\r\ntop_line_width = 1;\r\n\r\n%%\r\n% When creating the lines, set the |AlignVertexCenters| property to |'on'|.\r\n% This aligns the line positions with pixels on the screen so that the\r\n% graphics anti-aliased rendering doesn't make them appear to change\r\n% brightness.\r\n\r\nh_ax = ancestor(h_im,'axes');\r\n\r\nline(...\r\n    'Parent',h_ax,...\r\n    'XData',xv,...\r\n    'YData',yv,...\r\n    'LineWidth',bottom_line_width,...\r\n    'Color',dark_gray,...\r\n    'LineStyle','-',...\r\n    'AlignVertexCenters','on');\r\nline(...\r\n    'Parent',h_ax,...\r\n    'XData',xv,...\r\n    'YData',yv,...\r\n    'LineWidth',top_line_width,...\r\n    'Color',light_gray,...\r\n    'LineStyle','-',...\r\n    'AlignVertexCenters','on');\r\n\r\n%%\r\n% Give |pixelgrid| a try. You can find it on the <https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/71622-pixel-grid\/ \r\n% File Exchange>.\r\n\r\n##### SOURCE END ##### 4b4573f0bec7462bb584a41b127e6a5c\r\n-->","protected":false},"excerpt":{"rendered":"<div class=\"overview-image\"><img src=\"https:\/\/blogs.mathworks.com\/steve\/files\/pixel-grid-example.png\" class=\"img-responsive attachment-post-thumbnail size-post-thumbnail wp-post-image\" alt=\"\" decoding=\"async\" loading=\"lazy\" \/><\/div><p>ContentsIntroductionFind the image objectGet the spatial coordinates for drawing the outlineConstruct the x- and y-vectorsDraw the linesIntroductionSome years ago, I blogged about how to overlay a... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/steve\/2019\/06\/13\/pixelgrid\/\">read more >><\/a><\/p>","protected":false},"author":42,"featured_media":3315,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[272,725,250,90,36,747,32,575,68,116,190],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/3317"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/users\/42"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/comments?post=3317"}],"version-history":[{"count":3,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/3317\/revisions"}],"predecessor-version":[{"id":3333,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/3317\/revisions\/3333"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/media\/3315"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/media?parent=3317"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/categories?post=3317"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/tags?post=3317"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}