{"action":"created","comment":{"url":"https://api.github.com/repos/scikit-image/scikit-image/pulls/comments/30377158","id":30377158,"diff_hunk":"@@ -3,36 +3,137 @@\n __all__ = ['structural_similarity']\n \n import numpy as np\n+from scipy.ndimage.filters import uniform_filter, convolve1d\n \n from ..util.dtype import dtype_range\n-from ..util.shape import view_as_windows\n \n \n-def structural_similarity(X, Y, win_size=7,\n-                          gradient=False, dynamic_range=None):\n+def gaussian_filter2(X, sigma=1.5, size=11):\n+    \"\"\" nD Gaussian filter with specific window extent.\n+\n+    matches the implementation of Wang. et. al.\n+\n+    Parameters\n+    ----------\n+    X : ndarray\n+        image\n+    sigma : float\n+        Gaussian standard deviation (pixels)\n+    size : float\n+        Gaussian kernel extent (pixels)\n+\n+    Returns\n+    -------\n+    X : ndarray\n+        filtered image\n+\n+    Notes\n+    -----\n+    scipy.ndimage.gaussian is very similar, but uses a 13 tap FIR filter\n+    rather than the 11 tap one of Wang. et. al.\n+    \"\"\"\n+    radius = (size - 1) // 2\n+    r = np.arange(2*radius + 1) - radius\n+    filt = np.exp(-(r * r)/(2 * sigma * sigma))\n+    filt /= filt.sum()\n+    for ax in range(X.ndim):\n+        X = convolve1d(X, filt, axis=ax)\n+    return X\n+\n+\n+def _discard_edges(X, pad):\n+    \"\"\" Remove border of width pad from ndarray X.","path":"skimage/measure/_structural_similarity.py","position":46,"original_position":46,"commit_id":"1ca28df9f4b5aae96ecdbf576a7e3a5f3b7a47b5","original_commit_id":"1ca28df9f4b5aae96ecdbf576a7e3a5f3b7a47b5","user":{"login":"JDWarner","id":2184487,"avatar_url":"https://avatars.githubusercontent.com/u/2184487?v=3","gravatar_id":"","url":"https://api.github.com/users/JDWarner","html_url":"https://github.com/JDWarner","followers_url":"https://api.github.com/users/JDWarner/followers","following_url":"https://api.github.com/users/JDWarner/following{/other_user}","gists_url":"https://api.github.com/users/JDWarner/gists{/gist_id}","starred_url":"https://api.github.com/users/JDWarner/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/JDWarner/subscriptions","organizations_url":"https://api.github.com/users/JDWarner/orgs","repos_url":"https://api.github.com/users/JDWarner/repos","events_url":"https://api.github.com/users/JDWarner/events{/privacy}","received_events_url":"https://api.github.com/users/JDWarner/received_events","type":"User","site_admin":false},"body":"Oh right, that's where I put it ;)","created_at":"2015-05-15T00:33:21Z","updated_at":"2015-05-15T00:33:21Z","html_url":"https://github.com/scikit-image/scikit-image/pull/1511#discussion_r30377158","pull_request_url":"https://api.github.com/repos/scikit-image/scikit-image/pulls/1511","_links":{"self":{"href":"https://api.github.com/repos/scikit-image/scikit-image/pulls/comments/30377158"},"html":{"href":"https://github.com/scikit-image/scikit-image/pull/1511#discussion_r30377158"},"pull_request":{"href":"https://api.github.com/repos/scikit-image/scikit-image/pulls/1511"}}},"pull_request":{"url":"https://api.github.com/repos/scikit-image/scikit-image/pulls/1511","id":35459336,"html_url":"https://github.com/scikit-image/scikit-image/pull/1511","diff_url":"https://github.com/scikit-image/scikit-image/pull/1511.diff","patch_url":"https://github.com/scikit-image/scikit-image/pull/1511.patch","issue_url":"https://api.github.com/repos/scikit-image/scikit-image/issues/1511","number":1511,"state":"open","locked":false,"title":"ENH: structural_similarity: n-dimensional and multichannel support","user":{"login":"grlee77","id":6528957,"avatar_url":"https://avatars.githubusercontent.com/u/6528957?v=3","gravatar_id":"","url":"https://api.github.com/users/grlee77","html_url":"https://github.com/grlee77","followers_url":"https://api.github.com/users/grlee77/followers","following_url":"https://api.github.com/users/grlee77/following{/other_user}","gists_url":"https://api.github.com/users/grlee77/gists{/gist_id}","starred_url":"https://api.github.com/users/grlee77/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/grlee77/subscriptions","organizations_url":"https://api.github.com/users/grlee77/orgs","repos_url":"https://api.github.com/users/grlee77/repos","events_url":"https://api.github.com/users/grlee77/events{/privacy}","received_events_url":"https://api.github.com/users/grlee77/received_events","type":"User","site_admin":false},"body":"This pull requests implements the following enhancements / bug fix to the structural_similarity metric:\r\n\r\n-  extend the structural_similarity metric to n-dimensional arrays and multichannel images\r\n-  modify the implementation so that the results exactly match the reference implementation of the algorithm's original authors if the appropriate flags are set.\r\n- address possibly erroneous computation of the gradient\r\n\r\nThe existing implementation in scikit-image differs slightly from the one in the publication of Wang. et. al. referenced in the docstring.  The difference is primarily due to using a constant weighting rather than an 11-tap FIR Gaussian filter for the sliding window.  The default constant used for covariance normalization was also slightly different.  I added a note to the docstring informing the user of the settings needed to match this reference implementation, but by default left the behaviour so that the result will match prior versions of scikit-image. I think it is important to be able to exactly match the reference implementation for comparison to results in many existing publications in the literature.\r\n\r\nThe only thing in this pull request that is not fully backwards compatible is the computation of the gradient.  I do not personally use the gradient, but the existing implementation gave a result visually different from the result I get from code by the author of the following publication:\r\n\r\n*Avanaki, A. N. (2009). Exact global histogram specification optimized for structural similarity. Optical Review, 16, 613-621.*\r\nhttps://ece.uwaterloo.ca/~nnikvand/Coderep/SHINE%20TOOLBOX/SHINEtoolbox/ssim_sens.m\r\n\r\nI am not sure of the exact source of the difference in gradient computations as the equations look nominally the same, but I suspect it is a subtle difference in the call to view_as_windows in the old implementation vs. the explicit filtering used in my n-dimensional implementation and the 2D Matlab implementation referenced above.  Was anyone successfully using the gradient returned by the prior implementation in an application?  I couldn't find anywhere else in the code base that it was used.\r\n\r\nother minor points addressed are:\r\n- the computation speed of the scipy.ndimage based filtering used in this implementation is higher than the prior approach using view_as_windows.\r\n- tests were added to validate the results vs. the outputs of C and Matlab reference implementations for the 2D case\r\n- other algorithm constants that were previously hard coded (K1, K2) can be modified if desired via keyword arguments\r\n- allow the full structural similarity image to be returned if requested (via `full`=True), rather than just the mean value\r\n- allow computation of an \"image content weighted\" variant of structural similarity as proposed in\r\n*Wang, Z. and Shang, X.  Spatial pooling strategies for perceptual image quality assessment. Proc. IEEE Inter. Conf. Image. Proc. 2006.  p. 2945-2948.*\r\n\r\n\r\n","created_at":"2015-05-14T20:35:37Z","updated_at":"2015-05-15T00:33:21Z","closed_at":null,"merged_at":null,"merge_commit_sha":"32ce1a540199fd4ed4061b498d0e961cd46f1ed6","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/scikit-image/scikit-image/pulls/1511/commits","review_comments_url":"https://api.github.com/repos/scikit-image/scikit-image/pulls/1511/comments","review_comment_url":"https://api.github.com/repos/scikit-image/scikit-image/pulls/comments{/number}","comments_url":"https://api.github.com/repos/scikit-image/scikit-image/issues/1511/comments","statuses_url":"https://api.github.com/repos/scikit-image/scikit-image/statuses/1ca28df9f4b5aae96ecdbf576a7e3a5f3b7a47b5","head":{"label":"grlee77:ssim_ndim","ref":"ssim_ndim","sha":"1ca28df9f4b5aae96ecdbf576a7e3a5f3b7a47b5","user":{"login":"grlee77","id":6528957,"avatar_url":"https://avatars.githubusercontent.com/u/6528957?v=3","gravatar_id":"","url":"https://api.github.com/users/grlee77","html_url":"https://github.com/grlee77","followers_url":"https://api.github.com/users/grlee77/followers","following_url":"https://api.github.com/users/grlee77/following{/other_user}","gists_url":"https://api.github.com/users/grlee77/gists{/gist_id}","starred_url":"https://api.github.com/users/grlee77/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/grlee77/subscriptions","organizations_url":"https://api.github.com/users/grlee77/orgs","repos_url":"https://api.github.com/users/grlee77/repos","events_url":"https://api.github.com/users/grlee77/events{/privacy}","received_events_url":"https://api.github.com/users/grlee77/received_events","type":"User","site_admin":false},"repo":{"id":23844497,"name":"scikit-image","full_name":"grlee77/scikit-image","owner":{"login":"grlee77","id":6528957,"avatar_url":"https://avatars.githubusercontent.com/u/6528957?v=3","gravatar_id":"","url":"https://api.github.com/users/grlee77","html_url":"https://github.com/grlee77","followers_url":"https://api.github.com/users/grlee77/followers","following_url":"https://api.github.com/users/grlee77/following{/other_user}","gists_url":"https://api.github.com/users/grlee77/gists{/gist_id}","starred_url":"https://api.github.com/users/grlee77/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/grlee77/subscriptions","organizations_url":"https://api.github.com/users/grlee77/orgs","repos_url":"https://api.github.com/users/grlee77/repos","events_url":"https://api.github.com/users/grlee77/events{/privacy}","received_events_url":"https://api.github.com/users/grlee77/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/grlee77/scikit-image","description":"Image Processing SciKit (Toolbox for SciPy)","fork":true,"url":"https://api.github.com/repos/grlee77/scikit-image","forks_url":"https://api.github.com/repos/grlee77/scikit-image/forks","keys_url":"https://api.github.com/repos/grlee77/scikit-image/keys{/key_id}","collaborators_url":"https://api.github.com/repos/grlee77/scikit-image/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/grlee77/scikit-image/teams","hooks_url":"https://api.github.com/repos/grlee77/scikit-image/hooks","issue_events_url":"https://api.github.com/repos/grlee77/scikit-image/issues/events{/number}","events_url":"https://api.github.com/repos/grlee77/scikit-image/events","assignees_url":"https://api.github.com/repos/grlee77/scikit-image/assignees{/user}","branches_url":"https://api.github.com/repos/grlee77/scikit-image/branches{/branch}","tags_url":"https://api.github.com/repos/grlee77/scikit-image/tags","blobs_url":"https://api.github.com/repos/grlee77/scikit-image/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/grlee77/scikit-image/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/grlee77/scikit-image/git/refs{/sha}","trees_url":"https://api.github.com/repos/grlee77/scikit-image/git/trees{/sha}","statuses_url":"https://api.github.com/repos/grlee77/scikit-image/statuses/{sha}","languages_url":"https://api.github.com/repos/grlee77/scikit-image/languages","stargazers_url":"https://api.github.com/repos/grlee77/scikit-image/stargazers","contributors_url":"https://api.github.com/repos/grlee77/scikit-image/contributors","subscribers_url":"https://api.github.com/repos/grlee77/scikit-image/subscribers","subscription_url":"https://api.github.com/repos/grlee77/scikit-image/subscription","commits_url":"https://api.github.com/repos/grlee77/scikit-image/commits{/sha}","git_commits_url":"https://api.github.com/repos/grlee77/scikit-image/git/commits{/sha}","comments_url":"https://api.github.com/repos/grlee77/scikit-image/comments{/number}","issue_comment_url":"https://api.github.com/repos/grlee77/scikit-image/issues/comments{/number}","contents_url":"https://api.github.com/repos/grlee77/scikit-image/contents/{+path}","compare_url":"https://api.github.com/repos/grlee77/scikit-image/compare/{base}...{head}","merges_url":"https://api.github.com/repos/grlee77/scikit-image/merges","archive_url":"https://api.github.com/repos/grlee77/scikit-image/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/grlee77/scikit-image/downloads","issues_url":"https://api.github.com/repos/grlee77/scikit-image/issues{/number}","pulls_url":"https://api.github.com/repos/grlee77/scikit-image/pulls{/number}","milestones_url":"https://api.github.com/repos/grlee77/scikit-image/milestones{/number}","notifications_url":"https://api.github.com/repos/grlee77/scikit-image/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/grlee77/scikit-image/labels{/name}","releases_url":"https://api.github.com/repos/grlee77/scikit-image/releases{/id}","created_at":"2014-09-09T18:00:05Z","updated_at":"2015-03-05T22:53:39Z","pushed_at":"2015-05-11T20:31:05Z","git_url":"git://github.com/grlee77/scikit-image.git","ssh_url":"git@github.com:grlee77/scikit-image.git","clone_url":"https://github.com/grlee77/scikit-image.git","svn_url":"https://github.com/grlee77/scikit-image","homepage":"http://scikit-image.org","size":38252,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"scikit-image:master","ref":"master","sha":"a74ba0ec540c85fa9045769b9bd4bc7f906c2b94","user":{"login":"scikit-image","id":897180,"avatar_url":"https://avatars.githubusercontent.com/u/897180?v=3","gravatar_id":"","url":"https://api.github.com/users/scikit-image","html_url":"https://github.com/scikit-image","followers_url":"https://api.github.com/users/scikit-image/followers","following_url":"https://api.github.com/users/scikit-image/following{/other_user}","gists_url":"https://api.github.com/users/scikit-image/gists{/gist_id}","starred_url":"https://api.github.com/users/scikit-image/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/scikit-image/subscriptions","organizations_url":"https://api.github.com/users/scikit-image/orgs","repos_url":"https://api.github.com/users/scikit-image/repos","events_url":"https://api.github.com/users/scikit-image/events{/privacy}","received_events_url":"https://api.github.com/users/scikit-image/received_events","type":"Organization","site_admin":false},"repo":{"id":2014929,"name":"scikit-image","full_name":"scikit-image/scikit-image","owner":{"login":"scikit-image","id":897180,"avatar_url":"https://avatars.githubusercontent.com/u/897180?v=3","gravatar_id":"","url":"https://api.github.com/users/scikit-image","html_url":"https://github.com/scikit-image","followers_url":"https://api.github.com/users/scikit-image/followers","following_url":"https://api.github.com/users/scikit-image/following{/other_user}","gists_url":"https://api.github.com/users/scikit-image/gists{/gist_id}","starred_url":"https://api.github.com/users/scikit-image/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/scikit-image/subscriptions","organizations_url":"https://api.github.com/users/scikit-image/orgs","repos_url":"https://api.github.com/users/scikit-image/repos","events_url":"https://api.github.com/users/scikit-image/events{/privacy}","received_events_url":"https://api.github.com/users/scikit-image/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/scikit-image/scikit-image","description":"Image Processing SciKit (Toolbox for SciPy)","fork":false,"url":"https://api.github.com/repos/scikit-image/scikit-image","forks_url":"https://api.github.com/repos/scikit-image/scikit-image/forks","keys_url":"https://api.github.com/repos/scikit-image/scikit-image/keys{/key_id}","collaborators_url":"https://api.github.com/repos/scikit-image/scikit-image/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/scikit-image/scikit-image/teams","hooks_url":"https://api.github.com/repos/scikit-image/scikit-image/hooks","issue_events_url":"https://api.github.com/repos/scikit-image/scikit-image/issues/events{/number}","events_url":"https://api.github.com/repos/scikit-image/scikit-image/events","assignees_url":"https://api.github.com/repos/scikit-image/scikit-image/assignees{/user}","branches_url":"https://api.github.com/repos/scikit-image/scikit-image/branches{/branch}","tags_url":"https://api.github.com/repos/scikit-image/scikit-image/tags","blobs_url":"https://api.github.com/repos/scikit-image/scikit-image/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/scikit-image/scikit-image/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/scikit-image/scikit-image/git/refs{/sha}","trees_url":"https://api.github.com/repos/scikit-image/scikit-image/git/trees{/sha}","statuses_url":"https://api.github.com/repos/scikit-image/scikit-image/statuses/{sha}","languages_url":"https://api.github.com/repos/scikit-image/scikit-image/languages","stargazers_url":"https://api.github.com/repos/scikit-image/scikit-image/stargazers","contributors_url":"https://api.github.com/repos/scikit-image/scikit-image/contributors","subscribers_url":"https://api.github.com/repos/scikit-image/scikit-image/subscribers","subscription_url":"https://api.github.com/repos/scikit-image/scikit-image/subscription","commits_url":"https://api.github.com/repos/scikit-image/scikit-image/commits{/sha}","git_commits_url":"https://api.github.com/repos/scikit-image/scikit-image/git/commits{/sha}","comments_url":"https://api.github.com/repos/scikit-image/scikit-image/comments{/number}","issue_comment_url":"https://api.github.com/repos/scikit-image/scikit-image/issues/comments{/number}","contents_url":"https://api.github.com/repos/scikit-image/scikit-image/contents/{+path}","compare_url":"https://api.github.com/repos/scikit-image/scikit-image/compare/{base}...{head}","merges_url":"https://api.github.com/repos/scikit-image/scikit-image/merges","archive_url":"https://api.github.com/repos/scikit-image/scikit-image/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/scikit-image/scikit-image/downloads","issues_url":"https://api.github.com/repos/scikit-image/scikit-image/issues{/number}","pulls_url":"https://api.github.com/repos/scikit-image/scikit-image/pulls{/number}","milestones_url":"https://api.github.com/repos/scikit-image/scikit-image/milestones{/number}","notifications_url":"https://api.github.com/repos/scikit-image/scikit-image/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/scikit-image/scikit-image/labels{/name}","releases_url":"https://api.github.com/repos/scikit-image/scikit-image/releases{/id}","created_at":"2011-07-07T22:07:20Z","updated_at":"2015-05-14T12:36:19Z","pushed_at":"2015-05-15T00:21:30Z","git_url":"git://github.com/scikit-image/scikit-image.git","ssh_url":"git@github.com:scikit-image/scikit-image.git","clone_url":"https://github.com/scikit-image/scikit-image.git","svn_url":"https://github.com/scikit-image/scikit-image","homepage":"http://scikit-image.org","size":65610,"stargazers_count":700,"watchers_count":700,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":356,"mirror_url":null,"open_issues_count":179,"forks":356,"open_issues":179,"watchers":700,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/scikit-image/scikit-image/pulls/1511"},"html":{"href":"https://github.com/scikit-image/scikit-image/pull/1511"},"issue":{"href":"https://api.github.com/repos/scikit-image/scikit-image/issues/1511"},"comments":{"href":"https://api.github.com/repos/scikit-image/scikit-image/issues/1511/comments"},"review_comments":{"href":"https://api.github.com/repos/scikit-image/scikit-image/pulls/1511/comments"},"review_comment":{"href":"https://api.github.com/repos/scikit-image/scikit-image/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/scikit-image/scikit-image/pulls/1511/commits"},"statuses":{"href":"https://api.github.com/repos/scikit-image/scikit-image/statuses/1ca28df9f4b5aae96ecdbf576a7e3a5f3b7a47b5"}}}}