# スタンフォード/CS131/宿題2-3 キャニーエッジ検出 3

スポンサーリンク

## Question¶

(a) Suppose that the Canny edge detector successfully detects an edge in an image. The edge (see the figure above) is then rotated by θ, where the relationship between a point on the original edge $(x, y)$ and a point on the rotated edge $(x’, y’)$ is defined as
キャニーエッジ検出器が画像内のエッジをうまく検出したとする。その後、エッジ(上の図を参照のこと)は、元エッジのポイント$(x, y)$と回転エッジのポイント$(x’, y’)$の関係が以下のように表わせるθ回転をする。

$$x’=x\cos{\theta}\\ y’=x\sin{\theta}$$

Will the rotated edge be detected using the same Canny edge detector? Provide either a mathematical proof or a counter example.
この回転エッジは、同じキャニーエッジ検出器を用いて検出されるだろうか？数学的証明か反例のどちらか一方を示せ。

-Hint: The detection of an edge by the Canny edge detector depends only on the magnitude of its derivative. The derivative at point (x, y) is determined by its components along the x and y directions. Think about how these magnitudes have changed because of the rotation.
ヒント：キャニーエッジ検出器によるエッジの検出は、エッジの微分係数の大きさだけに依存している。ポイント(x, y)の微分係数は、エッジのx,y方向成分によって決定される。これらの大きさが回転によってどう変化するかについて考えてみる。

Suppose the magnitude of origin derivative is
ポイント(x, y)の微分係数の大きさを以下のように仮定すれば
$$M=\sqrt{dx^2+dy^2}=|dx|$$
The magnitude of rotated derivative is
ポイント$(x’, y’)$の微分係数の大きさは以下のように表わせる。
$$M’=\sqrt{(dxcos\theta)^2+(dxsin\theta)^2}=|dx|$$
So the magnitude doesn’t change, it can be detected using the same Canny edge detector.

(b) After running the Canny edge detector on an image, you notice that long edges are broken into short segments separated by gaps. In addition, some spurious edges appear. For each of the two thresholds (low and high) used in hysteresis thresholding, explain how you would adjust the threshold (up or down) to address both problems. Assume that a setting exists for the two thresholds that produces the desired result. Briefly explain your answer.

If long edges are broken into short segments, it means we lose some weak edges, so we should decrease the low threshold. If spurious edges appear, it means we come up with extra edges, so we should increase the high threshold.

## Extra Credit: Optimizing Edge Detector¶

One way of evaluating an edge detector is to compare detected edges with manually specified ground truth edges. Here, we use precision, recall and F1 score as evaluation metrics. We provide you 40 images of objects with ground truth edge annotations. Run the code below to compute precision, recall and F1 score over the entire set of images. Then, tweak the parameters of the Canny edge detector to get as high F1 score as possible. You should be able to achieve F1 score higher than 0.31 by carefully setting the parameters.
エッジ検出器を評価する1つの方法が、検出したエッジと手動で指定した正解エッジを比べることだ。ここでは、評価尺度として、精度、再現率、F1スコアを使用する。正解エッジ注釈付きの40の物体画像が用意してある。下のコードを実行して、全画像セットに対して精度、再現率、F1スコアを算出する。その後、可能な限り高いF1スコアを得るようにキャニーエッジ検出器のパラメータを微調整する。パラメータを注意深く設定することで、0.31を超える高いF1スコアを叩き出せるはずである。

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
from time import time
from skimage import io
from __future__ import print_function

%matplotlib inline
plt.rcParams['figure.figsize'] = (15.0, 12.0) # set default size of plots
plt.rcParams['image.interpolation'] = 'nearest'
plt.rcParams['image.cmap'] = 'gray'

The autoreload extension is already loaded. To reload it, use:

from edge import conv,gaussian_kernel,partial_x,partial_y,\
from os import listdir
from itertools import product

# Define parameters to test
sigmas = [1.25]
highs = [10.0]
lows = [9.0,9.25,9.50,9.75,9.90,9.95]

for sigma, high, low in product(sigmas, highs, lows):

print("sigma={}, high={}, low={}".format(sigma, high, low))
n_detected = 0.0
n_gt = 0.0
n_correct = 0.0

for img_file in listdir('images/objects'):

mask = (gt != 5) # 'don't' care region
gt = (gt == 0) # binary image of GT edges

edges = canny(img, kernel_size=5, sigma=sigma, high=high, low=low)

n_detected += np.sum(edges)
n_gt += np.sum(gt)
n_correct += np.sum(edges * gt)

p_total = n_correct / n_detected
r_total = n_correct / n_gt
f1 = 2 * (p_total * r_total) / (p_total + r_total)
print('Total precision={:.4f}, Total recall={:.4f}'.format(p_total, r_total))
print('F1 score={:.4f}'.format(f1))

sigma=1.25, high=10.0, low=9.0
Total precision=0.2864, Total recall=0.3615
F1 score=0.3196
sigma=1.25, high=10.0, low=9.25
Total precision=0.2905, Total recall=0.3571
F1 score=0.3204
sigma=1.25, high=10.0, low=9.5
Total precision=0.2944, Total recall=0.3528
F1 score=0.3210
sigma=1.25, high=10.0, low=9.75
Total precision=0.2984, Total recall=0.3484
F1 score=0.3215
sigma=1.25, high=10.0, low=9.9
Total precision=0.3007, Total recall=0.3457
F1 score=0.3216
sigma=1.25, high=10.0, low=9.95
Total precision=0.3015, Total recall=0.3448
F1 score=0.3217

スポンサーリンク

フォローする