0% found this document useful (0 votes)
99 views93 pages

Binary Processing

Using in Computer Vision Application
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
99 views93 pages

Binary Processing

Using in Computer Vision Application
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 93

Edge detection

Robotic & Vision Lab RoVis


• Convert a 2D image into a set of curves
– Extracts salient features of the scene
– More compact than pixels

Robotic & Vision Lab RoVis


surface normal discontinuity

depth discontinuity

surface color discontinuity

illumination discontinuity

• Edges are caused by a variety of factors

Robotic & Vision Lab RoVis


Characterizing edges

• An edge is a place of rapid change in the image


intensity function
intensity function
image (along horizontal scanline) first derivative

edges correspond to
Source: L. Lazebnik extrema of derivative

Robotic & Vision Lab RoVis


Tìm cạnh (Edge Detection) là một kĩ thuật xử ảnh được sử dụng để tìm kiếm
viền bao của của các đối tượng trong ảnh. Trong xử lý ảnh, công việc tìm
kiếm thực chất là tìm những khu vực bị mất liên tục về độ sáng

Robotic & Vision Lab RoVis


Image derivatives

• How can we differentiate a digital image F[x,y]?


– Option 1: reconstruct a continuous image, f, then
compute the derivative
– Option 2: take discrete derivative (finite difference)

How would you implement this as a linear filter?

: 1 -1 : -1
1

Source: S. Seitz

Robotic & Vision Lab RoVis


Robotic & Vision Lab RoVis
Robotic & Vision Lab RoVis
Robotic & Vision Lab RoVis
Robotic & Vision Lab RoVis
Robotic & Vision Lab RoVis
Image gradient
• The gradient of an image:
The gradient points in the direction of most rapid increase in intensity

The edge strength is given by the gradient magnitude:

The gradient direction is given by:

• how does this relate to the direction of the edge?


Source: Steve Seitz

Robotic & Vision Lab RoVis


Effects of noise

Noisy input image

Where is the edge?


Source: S. Seitz

Robotic & Vision Lab RoVis


Solution: smooth first

f*h

To find edges, look for peaks in


Source: S. Seitz

Robotic & Vision Lab RoVis


Associative property of convolution
• Differentiation is convolution, and convolution is
associative:

• This saves us one operation:

RoVis
Robotic & Vision Lab Source: S. Seitz
Derivative of Gaussian filter

x-direction y-direction

Robotic & Vision Lab RoVis


Robotic & Vision Lab RoVis
Sobel edge detector

Robotic & Vision Lab RoVis


The University of

Neighborhood Processing (filtering)


Second Image Derivatives Ontario

 Laplace operator  f    f   f 2

 f  f 2 2
 x 

 f  2  2  [ x y ]      f    f

x y  y  “divergence
rotationally invariant of gradient”
second derivative for 2D functions

0 0 0 0 -1 0 0 -1 0
-1 2 -1  0 2 0  -1 4 -1
0 0 0 0 -1 0 0 -1 0

Finite Difference Finite Difference


Second Order Second Order
Derivative in x Derivative in y
The University of

Ontario
The University of

Ontario
The University of

Ontario
•Lọc cạnh (sobel filter):

Sobel Là một phép lọc giúp tìm đường biên cho ảnh. Phép tính này dựa trên sự thay đổi đột ngột cường độ sáng của
2 pixel kế nhau. Bằng cách lấy đạo hàm cường độ sáng ta có được giá trị rất lớn. giá trị này biểu hiện đây là một
điểm nằn trên cạnh như hình:

Trong OpenCV để sử dụng Sobel cho một hình ảnh, ta sử dụng ma trận kernel tương đượng lấy đạo hàm bậc nhất sau:

F
 F i, j  * Gx
x
F
 F i, j  * Gy
y
2 2
F F
M i, j   
x y
F / y
 i, j   arctan( )
F / x

Robotic & Vision Lab RoVis


Ví dụ 3.6: dùng hàm filter2D để thực hiện lọc cạnh của hình như sau:

Robotic & Vision Lab RoVis


Sobel edge detector

Robotic & Vision Lab RoVis


Robotic & Vision Lab RoVis
® © Peter Corke
a university for the
real world
CRICOS No. 00213J
Sobel edge operator >> isobel(im)

The edge detected image can be obtained from the sobel gradient by
using a threshold value
Robotic & Vision Lab RoVis
Basic Steps followed in Sobel Edge Detection:
1. Obtain the gradient of the image.
2. Find the magnitude
3. Threshold the gradient image.
A=imread('peppers.png');
B=rgb2gray(A);
C=double(B);
for i=1:size(C,1)-2
for j=1:size(C,2)-2
%Sobel mask for x-direction:
Gx=((2*C(i+2,j+1)+C(i+2,j)+C(i+2,j+2))-
(2*C(i,j+1)+C(i,j)+C(i,j+2)));
%Sobel mask for y-direction:
Gy=((2*C(i+1,j+2)+C(i,j+2)+C(i+2,j+2))-
(2*C(i+1,j)+C(i,j)+C(i+2,j)));

%The gradient of the image


%B(i,j)=abs(Gx)+abs(Gy);
B(i,j)=sqrt(Gx.^2+Gy.^2);

end
end
figure,imshow(B); title('Sobel gradient');

Robotic & Vision Lab RoVis


%Define a threshold value
Thresh=100;
B=max(B,Thresh);
B(B==round(Thresh))=0;

B=uint8(B);
figure,imshow(~B);title('Edge
detected Image');

Robotic & Vision Lab RoVis


SOBEL EDGE DETECTION USING ‘edge’ FUNCTION:

%Input Image
A=imread('coins.png');

%Image obtained using MATLAB function 'edge'


[E,th]=edge(A,'sobel','nothinning');
figure,imshow(E);title('Image obtained using MATLAB function')

Robotic & Vision Lab RoVis


Edge Detection without using the 'edge' function:

%Input Image
A=imread('coins.png');
%Preallocate the matrices with zeros
I=zeros(size(A));
%Filter Masks
F1=[-1 0 1;-2 0 2; -1 0 1];
F2=[-1 -2 -1;0 0 0; 1 2 1];
A=double(A);
for i=1:size(A,1)-2
for j=1:size(A,2)-2
%Gradient operations
Gx=sum(sum(F1.*A(i:i+2,j:j+2)));
Gy=sum(sum(F2.*A(i:i+2,j:j+2)));

%Magnitude of vector
I(i+1,j+1)=sqrt(Gx.^2+Gy.^2);

end
end
I=uint8(I);

Robotic & Vision Lab RoVis


figure,imshow(I);title('Filtered Image');
%Define a threshold value
Thresh=210;
B=max(I,Thresh);
B(B==round(Thresh))=0;

B=im2bw(B);
figure,imshow(B);title('Edge detected Image');

Robotic & Vision Lab RoVis


Trong opencv có hàm:
cv::Sobel(cv::InputArray src, cv::OutputArray dst, int ddepth, int dx,
int dy, int ksize = 3, double scale = (1,0) , double delta = (0,0),
int borderType = 4);

Với
o src: Là ảnh gốc.
o dst: Là ảnh sau khi thực hiện phép lọc số ảnh.
o ksize: Là kích thước của ma trận lọc. Giá trị mặc định là 3.
o ddepth: Làđộ sâu của ảnh sau phép lọc: VD: CV_32F, CV_64F,...
o dx: Là đạo hàm theo hướng x.
o dy: Là đạo hàm theo hướng y.
o Để đạo hàm theo hướng nào thì ta đặt giá trị đó lên 1.
o scale và delta: Là 2 thông số tùy chọn cho việc tính giá trị đạo hàm lưu giá
trị vi sai vào ảnh sau phép lọc. Mặc định là 1 và 0.
o borderType: Là phương pháp để ước lượng và căn chỉnh các điểm ảnh
nếu phép lọc chúng vượt ra khỏi giới hạn của ảnh. giá trị mặc định là 4.

Robotic & Vision Lab RoVis


Preprocessing
Mat workImg = Mat(src);
workImg = src.clone();
// Step 1: Noise reduction
cv::GaussianBlur(src, workImg, cv::Size(5, 5), 1.4);
Calculating gradients
Next, we'll calculate gradient magnitudes and orientations separately. We start with calculating the sobel of th
image:

// Step 2: Calculating gradient magnitudes and directions


Mat magX = Mat(src.rows, src.cols, CV_32F);
Mat magY = Mat(src.rows, src.cols, CV_32F);
cv::Sobel(workImg, magX, CV_32F, 1, 0, size);
cv::Sobel(workImg, magY, CV_32F, 0, 1, size);
next, we calculate the slope at each point. This is simply dividing the Y derivative by X:

Mat direction = Mat(workImg.rows, workImg.cols, CV_32F);


cv::divide(magY, magX, direction);
//Step 3: Next we calculate the magnitude of the gradient at each pixel:

Mat sum = Mat(workImg.rows, workImg.cols, CV_64F);


Mat prodX = Mat(workImg.rows, workImg.cols, CV_64F);
Mat prodY = Mat(workImg.rows, workImg.cols, CV_64F);
cv::multiply(magX, magX, prodX);
cv::multiply(magY, magY, prodY);
sum = prodX + prodY;

Robotic & Vision Lab RoVis


cv::sqrt(sum, sum);
Ví dụ 5.2: tìm cạnh biên của hình sau sử dụng thư viện opencv [61]

Robotic & Vision Lab RoVis


Canny edge detection

1. Smooth the Image with Gaussian Filter


2. Compute the Gradient Magnitude and
Orientation using finite-difference
approximations for the partial derivatives,
3. Apply nonmaxima suppression to the gradient
magnitude,
4. Use the double thresholding algorithm to detect
and link edges

Robotic & Vision Lab RoVis


Smoothing

• Let I[i,j] denote the image and G[i,j,σ] be a


Gaussian smoothing filter σ is the spread of the
Gaussian and controls the degree of smoothing.
• The result of convolution of I[i,j] with G[i,j,σ] gives
an array of smoothed data as:
s[i,j]= G[i,j,σ] * I[i,j]

Robotic & Vision Lab RoVis


Gradient Calculation

• Firstly, the gradient of the smoothed array S[i,j] is


used to produce the x and y partial derivatives
• If the Sobel operator is used to obtain a
2-D spatial gradient,

Robotic & Vision Lab RoVis


Gradient Calculation

S
 S i, j * Gx
x
S
 S i, j * Gy
y
2 2
S S
M i, j   
x y
S / y
 i, j   arctan( )
S / x
Robotic & Vision Lab RoVis
Non-Maximum Suppression

We wish to mark points along the curve where the magnitude is biggest.
We can do this by looking for a maximum along a slice normal to the curve
(non-maximum suppression). These points should form a curve. There are
then two algorithmic issues: at which point is the maximum, and where is the
next one?
Robotic & Vision Lab RoVis
Non-Maximum Suppression

• Suppress the pixels in ‘Gradient Magnitude Image’


which are not local maximum

 if S x, y   S x , y 
 S  x , y 
M x, y    & S x, y   S x , y 

x, y  0 otherwise

x, y 
x,y  and x,y  are the neighbors of x,y  in S
x, y along the direction normal to an edge

Robotic & Vision Lab RoVis


Nonmaxima Suppression

• Once the edge direction is known, the next step is to relate the
edge direction to a direction that can be traced in an image. So if
the pixels of a 5x5 image are aligned as follows:

• x x x x x
x x x x x
x x a x x
x x x x x
x x x x x

• Then, it can be seen by looking at pixel "a", there are only four
possible directions when describing the surrounding pixels
• 0 degrees (in the horizontal direction),
• 45 degrees (along the positive diagonal),
• 90 degrees (in the vertical direction), or
• 135 degrees (along the negative diagonal).
Robotic & Vision Lab RoVis
Non-Maximum Suppression

Sy 2
tan θ 
Sx 3 1

0 : -0.4142  tan θ  0.4142


1 : 0.4142  tan θ  2.4142 0
2 : tan θ  2.4142
3 : - 2.4142  tan θ  0.4142

Robotic & Vision Lab RoVis


Edge direction
• any edge direction falling within the yellow range (0 to 22.5 &
157.5 to 180 degrees) is set to 0 degrees.
• Any edge direction falling in the green range (22.5 to 67.5
degrees) is set to 45 degrees.
• Any edge direction falling in the blue range (67.5 to 112.5
degrees) is set to 90 degrees.
• And finally, any edge direction falling within the red range (112.5
to 157.5 degrees) is set to 135 degrees.

Robotic & Vision Lab RoVis


for (int i = 0; i < Arows; i++) {
for (int j = 0; j < Acols; j++) {
if ((angle.at<float>(i, j) >= 0) && (angle.at<float>(i, j) < 22.5) || (angle.at<float>(i, j) >=
157.5) && (angle.at<float>(i, j) < 202.5) || (angle.at<float>(i, j) >= 337.5) && (angle.at<float>(i, j) <= 360))
{
angle2.at<float>(i, j) = 0;
}
else if ((angle.at<float>(i, j) >= 22.5) && (angle.at<float>(i, j) < 67.5) ||
(angle.at<float>(i, j) >= 202.5) && (angle.at<float>(i, j) < 247.5))
{
angle2.at<float>(i, j) = 45;
}
else if ((angle.at<float>(i, j) >= 67.5 && angle.at<float>(i, j) < 112.5) ||
(angle.at<float>(i, j) >= 247.5 && angle.at<float>(i, j) < 292.5))
{
angle2.at<float>(i, j) = 90;
}
else if ((angle.at<float>(i, j) >= 112.5 && angle.at<float>(i, j) < 157.5) ||
(angle.at<float>(i, j) >= 292.5 && angle.at<float>(i, j) < 337.5))
{
angle2.at<float>(i, j) = 135;
}
}
}

Robotic & Vision Lab RoVis


Nonmaximum suppression
Now, we want to remove the pixels(set their values to
0) which are not edges. You would say that we can
simply pick the pixels with the highest gradient values
and those are our edges. However, in real-world
images, gradient doesn’t simply peak at one pixel,
rather it’s very high on the pixels near the edge as
well. So, we pick the local maxima in a neighborhood
of 3×3 in the direction of gradients.

• Consider the four direction d1,d2,d3,d4 identified by the


0o,45o,90o,135o orientations
• For each pixel (i,j):
• Find the direction, dk, which best approximates the direction
• If M[i,j] is smaller than at least one of its two neighbors along dk,
assign I[i,j]=0; otherwise assign I[i,j]=M[i,j]

Robotic & Vision Lab RoVis


for (int i = 1; i < Arows - 1; i++) {
for (int j = 1; j < Acols - 1; j++) {
if (angle2.at<float>(i, j) == 0) {
Mat temp = (Mat_<double>(1, 3) << double(G.at<float>(i, j)),
double(G.at<float>(i, j + 1)), double(G.at<float>(i, j - 1)));
minMaxLoc(temp, NULL, &MaxVal, NULL, NULL);
if (G.at<float>(i, j) == MaxVal) {
nonmax.at<double>(i, j) = 1;
}
else nonmax.at<double>(i, j) = 0;
}
else if (angle2.at<float>(i, j) == 45) {
Mat temp = (Mat_<double>(1, 3) << double(G.at<float>(i, j)),
double(G.at<float>(i + 1, j - 1)), double(G.at<float>(i - 1, j + 1)));
minMaxLoc(temp, NULL, &MaxVal, NULL, NULL);
if (G.at<float>(i, j) == MaxVal) {
nonmax.at<double>(i, j) = 1;
}
else nonmax.at<double>(i, j) = 0;
}

Robotic & Vision Lab RoVis


Hysteresis Thresholding

• The image output by NONMAX- SUPPRESSION I[i,j] still


contains the local maxima created by noise. How do we get
rid of these?
• If we set a low threshold in the attempt of capturing true but
weak edges, some noisy maxima will be accepted too (false
contours);
• The values of true maxima along a connected contours may
fluctuate above and below the threshold, fragmenting the result
edge.
• A solution is hysteresis thresholding

Robotic & Vision Lab RoVis


Hysteresis Thresholding

• If the gradient at a pixel is above ‘High’, declare it an


‘edge pixel’
• If the gradient at a pixel is below ‘Low’, declare it a
‘non-edge-pixel’
• If the gradient at a pixel is between ‘Low’ and ‘High’
then declare it an ‘edge pixel’ if and only if it is
connected to an ‘edge pixel’ directly or via pixels
between ‘Low’ and ‘ High’
Robotic & Vision Lab RoVis
Robotic & Vision Lab RoVis
Hysteresis Thresholding

• Two threshold values, TL and TH are applied to I[i,j].


Here TL < TH
• For all the edge points in I[i,j], and scanning I[i,j] in a
fixed order:
1. Locate the next unvisited edge pixel, I[i,j], such tht I[i,j]>TH;
2. Starting from I[i,j], follow the chains of connected local
maxima, in both directions perpendicular to the edge
normal, as long as I[i,j]>TL. Mark all visited points, and save
a list of all locations of all points in the connected contour
found.
The output is a set of list, each describing the position
of a connected contour in the image.

Robotic & Vision Lab RoVis


for (int i = 0; i < Arows; i++) {
for (int j = 0; j < Acols; j++) {
if (nonmax.at<double>(i, j) < T_Low) {
T_res.at<double>(i, j) = 0;
}
else if (nonmax.at<double>(i, j) > T_High) {
T_res.at<double>(i, j) = 255;
}
else if (nonmax.at<double>(i + 1, j) > T_High || nonmax.at<double>(i - 1, j) > T_High ||
nonmax.at<double>(i, j + 1) > T_High || nonmax.at<double>(i, j - 1) > T_High || nonmax.at<double>(i - 1, j - 1) > T_High ||
nonmax.at<double>(i - 1, j + 1) > T_High || nonmax.at<double>(i + 1, j + 1) > T_High || nonmax.at<double>(i + 1, j - 1) >
T_High) {
T_res.at<double>(i, j) = 255;
}
}
}

Robotic & Vision Lab RoVis


Ví dụ 5.3: Tìm biên của hình sau bằng giải thuật canny

Tìm gradient của hình sử dụng kernel:

Robotic & Vision Lab RoVis


Độ lớn của gradient: G ( x, y )  Gx2  Gy2
Ta có 8 hướng như sau:

Tìm góc:
Áp dụng Ngưỡng Hysteresis

Áp dụng ngưỡng là 40

Robotic & Vision Lab RoVis


void Canny(InputArray image, OutputArray edges, double threshold1, double threshold2,
int apertureSize=3, bool L2gradient=false )
Parameters:
image – single-channel 8-bit input image.
•edges – output edge map; it has the same size and type as image .
•threshold1 – first threshold for the hysteresis procedure.
•threshold2 – second threshold for the hysteresis procedure.
•apertureSize – aperture size for the Sobel() operator.
•L2gradient – a flag, indicating whether a more accurate norm
int main( )
{
Mat src1;
src1 = imread("lena.jpg", CV_LOAD_IMAGE_COLOR);
namedWindow( "Original image", CV_WINDOW_AUTOSIZE );
imshow( "Original image", src1 );

Mat gray, edge, draw;


cvtColor(src1, gray, CV_BGR2GRAY);

Canny( gray, edge, 50, 150, 3);

edge.convertTo(draw, CV_8U);
namedWindow("image", CV_WINDOW_AUTOSIZE);
imshow("image", draw);

waitKey(0);
return 0; Robotic & Vision Lab RoVis
Ví dụ 5.2: tìm cạnh biên của hình sau sử dụng thư viện opencv [61]

Robotic & Vision Lab RoVis


Edge based template matching
1. Creating an edge based template model
Step 1: Find the intensity gradient of the image
Step 2: Apply non-maximum suppression
Step 3: Do hysteresis threshold
Step 4: Save the data set
we created from the template image which contains a set of points and its gradients in X and Y direction

2. Find the edge based template model


We can also find the gradients in the search image (S)
In the matching process, the template model should be compared to the search image at all locations
using a similarity measure. The idea behind similarity measure is to take the sum of all normalized dot
products of gradient vectors of the template image and search the image over all points in the model
data set. This results in a score at each point in the search image.

Robotic & Vision Lab RoVis


cvSobel( src, Sdx, 1, 0, 3 ); // find X derivatives
cvSobel( src, Sdy, 0, 1, 3 ); // find Y derivatives
for( i = 0; i < Ssize.height; i++ )
{
for( j = 0; j < Ssize.width; j++ )
{
partialSum = 0; // initilize partialSum measure
for(m=0;m<noOfCordinates;m++)
{
curX = i + cordinates[m].x ; // template X coordinate
curY = j + cordinates[m].y ; // template Y coordinate
iTx = edgeDerivativeX[m]; // template X derivative
iTy = edgeDerivativeY[m]; // template Y derivative
if(curX<0 ||curY<0||curX>Ssize.height-1 ||curY>Ssize.width-1)
continue;

_Sdx = (short*)(Sdx->data.ptr + Sdx->step*(curX));


_Sdy = (short*)(Sdy->data.ptr + Sdy->step*(curX));

iSx=_Sdx[curY]; // get curresponding X derivative from source image


iSy=_Sdy[curY];// get curresponding Y derivative from source image

if((iSx!=0 || iSy!=0) && (iTx!=0 || iTy!=0))


{
//partial Sum = Sum of(((Source X derivative* Template X drivative)
//+ Source Y derivative * Template Y derivative)) / Edge
//magnitude of(Template)* edge magnitude of(Source))
partialSum = partialSum + ((iSx*iTx)+(iSy*iTy))*
(edgeMagnitude[m] * matGradMag[curX][curY]);

} Robotic & Vision Lab RoVis


findContours(InputOutputArray image, OutputArrayOfArrays contours, OutputArray
hierarchy, int mode, int method, Point offset=Point())
• image : hình ảnh cần tìm biên, là ảnh nhị phân.
• contours : lưu trữ các đường biên tìm được, mỗi đường biên được lưu trữ dưới dạng
một vector của các điểm.
• hierarchy : chứa thông tin về hình ảnh như số đường viền, xếp hạng các đường viền
theo kích thước, trong ngoài, ..
mode :
CV_RETR_EXTERNAL : khi sử dựng cờ này nó chỉ lấy ra những đường biên bên ngoài, nhưng
biên bên trong của vật thể bị loại bỏ.
CV_RETR_LIST : Khi sử dụng cờ này nó lấy ra tất cả các đường viền tìm được.
CV_RETR_CCOMP : khi sử dụng cờ này nó lấy tất cả những đường biên và chia nó làm 2 level,
những đường biên bên ngoài đối tượng, và những đường biên bên trong đối tượng.
CV_RETR_TREE : khi sử dụng cờ này nó lấy tất cả các đường biên và tạo ra một hệ thống
phân cấp đầy đủ của những đường lồng nhau.

Robotic & Vision Lab RoVis


drawContours(InputOutputArray image, InputArrayOfArrays contours, int contourIdx, const
Scalar& color, int thickness=1, int lineType=8, InputArray hierarchy, int
maxLevel=INT_MAX, Point offset=Point() )
 Image : hình ảnh đích.
 contours : tất cả những đường biên đầu vào.
 color : màu của đường biên.
 thickness : độ dày của các đường được vẽ.
 hierarchy : thông tin về phân cấp các đường biên, như trên hàm findContour.

Ví dụ 5.5: tìm countour của hình sau [63]

Robotic & Vision Lab RoVis


int main()
{
Mat image;
image = imread("shape.jpg", 1);
namedWindow("Display window", CV_WINDOW_AUTOSIZE);
imshow("Display window", image);
Mat gray;
cvtColor(image, gray, CV_BGR2GRAY);
Canny(gray, gray, 100, 200, 3);
/// Find contours
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
RNG rng(12345);
findContours(gray, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
/// Draw contours
Mat drawing = Mat::zeros(gray.size(), CV_8UC3);
for (int i = 0; i < contours.size(); i++)
{
Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
drawContours(drawing, contours, i, color, 2, 8, hierarchy, 0, Point());
}

imshow("Result window", drawing);


waitKey(0);
return 0;
}

Robotic & Vision Lab RoVis


for (int i = 0; i < contours.size(); i++)
{
// Find the area of contour
double a = contourArea(contours[i], false);
if (a > largest_area) {
largest_area = a; cout << i << " area " << a << endl;
// Store the index of largest contour
largest_contour_index = i;
// Find the bounding rectangle for biggest contour
bounding_rect = boundingRect(contours[i]);
}
}
Scalar color(255, 255, 255); // color of the contour in the
//Draw the contour and rectangle
drawContours(src, contours, largest_contour_index, color, CV_FILLED, 8, hierarchy);
rectangle(src, bounding_rect, Scalar(0, 255, 0), 2, 8, 0);
namedWindow("Display window", CV_WINDOW_AUTOSIZE);
imshow("Display window", src);
waitKey(0);
return 0;

Robotic & Vision Lab RoVis


Robotic & Vision Lab RoVis
Robotic & Vision Lab RoVis
• Rather than convolve the image with the gaussian and take the second order derivative of
the result, you can actually take the 2nd derivative of the gaussian itself.

Robotic & Vision Lab RoVis


#include<opencv2/opencv.hpp>
#include<iostream>
for (int i = -kerLen; i <= kerLen; i++)
using namespace std; {
using namespace cv; for (int j = -kerLen; j <= kerLen; j++)
{
void main() kernel.at<double>(i + kerLen, j + kerLen) =
{ exp(-((pow(j, 2) + pow(i, 2)) /
Mat srcImage = imread("F:\\opencv_re_learn\\2.jpg"); (pow(delta, 2) * 2)))*
(((pow(j, 2) + pow(i, 2) - 2 *
if (!srcImage.data) { pow(delta, 2)) / (2 * pow(delta, 4))));
cout << "falied to read" << endl;
}
system("pause"); }
return;
} Mat laplacian;
Mat srcGray; filter2D(src, laplacian, src.depth(), kernel);
cvtColor(srcImage, srcGray, CV_BGR2GRAY);
//高斯滤波
GaussianBlur(srcGray, srcGray, Size(3, 3),
0, 0, BORDER_DEFAULT);
//拉普拉斯变换
Mat laplace_result;
Laplacian(srcGray, laplace_result, CV_16S, 3);
convertScaleAbs(laplace_result, laplace_result);
imshow("src", srcImage);
imshow("Laplace_result", laplace_result);
waitKey(0);

Robotic & Vision Lab RoVis


Robotic & Vision Lab RoVis
Robotic & Vision Lab RoVis
Robotic & Vision Lab RoVis
Robotic & Vision Lab RoVis
Robotic & Vision Lab RoVis
Robotic & Vision Lab RoVis
Mat laplacian;
filter2D(src, laplacian, src.depth(), kernel);

imshow("laplacian", laplacian);
for (int y = 1; y < result.rows - 1; ++y)
{
for (int x = 1; x < result.cols - 1; ++x)
{
result.at<uchar>(y, x) = 0;
if (laplacian.at<double>(y - 1, x)*laplacian.at<double>(y + 1, x) < 0)
{
result.at<uchar>(y, x) = 255;
}
if (laplacian.at<double>(y, x - 1)*laplacian.at<double>(y, x + 1) < 0)
{
result.at<uchar>(y, x) = 255;
}
if (laplacian.at<double>(y + 1, x - 1)*laplacian.at<double>(y - 1, x + 1) < 0)
{
result.at<uchar>(y, x) = 255;
}
if (laplacian.at<double>(y - 1, x - 1)*laplacian.at<double>(y + 1, x + 1) < 0)
{
result.at<uchar>(y, x) = 255;
}
}
}
threshold(laplacian, result, 1, 255, CV_THRESH_BINARY);

Robotic & Vision Lab RoVis


Difference od Gaussian (DOG)

Mat im = imread("dog.jpg", 0);


Mat dw;
pyrDown(im, dw);
Mat kernel = getStructuringElement(MORPH_ELLIPSE, Size(7, 7));
morphologyEx(dw, dw, CV_MOP_DILATE, kernel);

Mat g1, g2, dog, bw;


GaussianBlur(dw, g1, Size(31, 31), 21, 21);
GaussianBlur(dw, g2, Size(31, 31), 31, 31);
//GaussianBlur(dw, g2, Size(65, 65), 31, 31);
dog = g1 - g2;
normalize(dog, dog, 0, 255, NORM_MINMAX);

threshold(dog, bw, 0, 255, CV_THRESH_BINARY | CV_THRESH_OTSU);


imshow("DOG1", bw);

Robotic & Vision Lab RoVis


Robotic & Vision Lab RoVis
Interest point detection

Robotic & Vision Lab RoVis


Harris Corner detection

Robotic & Vision Lab RoVis


Corner detection
Giả sử để tìm góc của hình ta di chuyển một ô cửa sổ nhỏ trên hình. Có 3 trường hợp xảy ra
Trường hợp 1: Không có gì thay đổi khi ta di chuyển khung hình theo mọi hướng=> ta đang di chuyển trên vùng phẳng có cường độ ánh sáng
hay màu sáng đều nhau

Trường hợp 2: Không có gì thay đổi khi ta di chuyển khung hình dọc theo đường thẳng=> ta đang di chuyển trên đường biên hay cạnh.

Trường hợp 3: Thay đổi lớn khi ta di chuyển khung hình theo mọi hướng=> ta đang di chuyển ở góc

Robotic & Vision Lab RoVis


Khi ta di chuy ển khung hình, đ ộ sai lệch về cường độ được tính theo công
thức summing up the squared differences (SSD)

E (u , v)   w( x, y )[ I ( x  u , y  v)  I ( x, y )]2
x, y

Trong đó, E(u, v) Tổng số bình phương giá trị độ lệch, w(x, y) là cửa sổ tại (x,
y), I(x, y) và I(x+ u, y + v) là giá trị cường độ sáng của pixel tại các vị trí (x,
y) và (u + x, v + y).

KHi di chuyển một đoạn (u, v) nhỏ ta có hàm tương đương


u 
E (u, v)  [u v] M  
v 
Trong đó, M là một ma trận:
 I x2 I x I y 
M   w( x, y )  2
 .
x, y  I x I y I y 

gọi λ1 và λ2 là các trị riêng của M. Khi đó, biểu thức biểu hiện đáp ứng góc
sẽ quyết định xem cửa sổ w có chứa góc hay là không.
R  det M  k (trace M )2
Với
det M  12
trace M  1  2

Robotic & Vision Lab RoVis


Robotic & Vision Lab RoVis
Để xác định được “corner” sử dụng Harris Corner Detection Algorithm:

 Bước 1: tính Gradient của vùng pixel I x , I y ;

 I x2 I x I y 
 Bước 2: xây dựng ma trận M   w( x, y )  2

x, y  x y y 
I I I

 Bước 3: tính giá trị R  det M  k (trace M )2 .

Với k là “Harris detector free parameter”, thường có giá trị 0,04-0,06.


Khi đã có được giá trị R, chúng ta sẽ xác định xem vùng pixel này có phải
“corner” không:

 Nếu giá trị |R| nhỏ thì vùng pixel đó không chứa thông tin có giá trị,
còn gọi là “flat” region;
 Nếu R  0 , tức là khi 1  2 hoặc 2  1 , thì vùng pixel đó chỉ
chứa cạnh “edge”;
 Nếu giá trị R lớn, tức là khi 1  1, 2  1 và 1  2 , thì vùng
pixel này chứa góc “corner”.

Robotic & Vision Lab RoVis


double a[] = {1.96 , -6.49 , -0.47 , -7.20 , -0.65,
-6.49 , 3.80 ,-6.39 , 1.50 , -6.34,
-0.47 , -6.39 , 4.17 , -1.51 , 2.67,
-7.20 , 1.50 , -1.51 , 5.70 , 1.80,
Với giải thuật Shi-Tomasi để tìm góc R= min(1 , 2 ) -0.65 , -6.34 , 2.67 , 1.80 , -7.10 };

CvMat mat = cvMat(5, 5, CV_64FC1, a);


CvMat* evec = cvCreateMat(5, 5, CV_64FC1);
CvMat* eval = cvCreateMat(1, 5, CV_64FC1);

cvZero(evec);
cvZero(eval);

cvEigenVV(&mat, evec, eval, DBL_EPSILON, 0, 0);


// print matrix
for (int i = 0; i < eval->rows; i++)
{
Hình 6.32 Giải thuật tìm cạnh Shi-Tomasi [78] for (int j = 0; j < eval->cols; j++)
{
Khi 1 , 2 lớn hơn một giá trị minimum, vùng đó sẽ là có xuất hiện góc CvScalar scal = cvGet2D(eval, i, j);
printf("%f\t", scal.val[0]);
}
printf("\n");
}

cvReleaseMat(&evec);
cvReleaseMat(&eval);

16.094837 8.865457 0.864028 -6.228747 -11.065575

Robotic & Vision Lab RoVis


Ví dụ 6.10: Vị trí của hình sau có phải là góc. Sử sụng window là 2x2 và sử dụng giải thuật Harris

Tính Gradient của vùng pixel theo phương x, I x có tổng cộng 14 ô, và tổng Tính Gradient của vùng pixel theo phương y, I y có tổng cộng 14 ô, và tổng
là 14 => I x =14
là: 14 => I y =14

Hình 6.35 Tính gradient theo phương y [79]


Hình 6.34 Tính gradient theo phương x [79]
0 1  0 0
0 1 0 0 0 0   (0  0)  (0  1)  1 , 0 1    (0  0)  (1  0)   1
1   (1  0)  (1  1)   1 , 0 1    (0  0)  (1  0)   1
   
 1   0 1 1 1
1   (1  0)  (1  1)   1 …… 0 1   (0  1)  (1  1)   1
0 1 1 1  1  
1 1   (1  0)  (1  1)   1 …… 0 1   (1  1)  (1  0)   1
   

Robotic & Vision Lab RoVis


Tính Gradient I x I y

Hình 6.36 Tính gradient theo phương x,y [79]

 I x I y =2

 all i , j in N
 I (i, j ) 
2
 I ( x, y )   I ( x, y )  
all i , j in N

  
 x 
  
 x   y  
 
 i, j i, j
 M ( x, y )   all i , j in N 2 
 I ( x, y )   I ( x, y )   I (i, j ) 
all i , j in N
 

 i , j  x   y     
i, j  y 
14 2 
 M ( x, y )    => 1  12, 2  14
 2 14 
Cả 2 gái trị eigen đều lớn=> đây là góc

Robotic & Vision Lab RoVis


Ví dụ 6.11: Đây có phải là vị trí góc không

Hình 6.37 Hình cho ví dụ 6.11 [79]

Tương tự cách tính trên ta có

• Tổng tất cả (I/x)^2= (2^2)*7=28

• Tổng tất cả (I/y)^2= 0

• Tổng tất cả (I/x)*(I/y)= 0


M= [28 0 ; 0 0]

Eigen là: 0 và 28

Robotic & Vision Lab RoVis


Robotic & Vision Lab RoVis
Robotic & Vision Lab RoVis
Robotic & Vision Lab RoVis
Ví dụ 6.12: tìm vị trí góc của hình sau sử dụng opencv

filter2D(gray, gradientX, -1, dx, Point(-1, -1), 0, BORDER_REFLECT); // Ix


filter2D(gray, gradientY, -1, dy, Point(-1, -1), 0, BORDER_ISOLATED); // Iy

Mat gradientX_temp, gradientY_temp;


gradientX.convertTo(gradientX_temp, CV_32F);
gradientY.convertTo(gradientY_temp, CV_32F);

Mat Ix2tem, Iy2tem, Ixytem;


Ix2tem = gradientX_temp.mul(gradientX_temp);
Iy2tem = gradientY_temp.mul(gradientY_temp);
Ixytem = gradientX_temp.mul(gradientY_temp);

Mat Ix2, Iy2, Ixy;


filter2D(Ix2tem, Ix2, -1, gfilter, Point(-1, -1), 0, BORDER_DEFAULT);
filter2D(Iy2tem, Iy2, -1, gfilter, Point(-1, -1), 0, BORDER_DEFAULT);
filter2D(Ixytem, Ixy, -1, gfilter, Point(-1, -1), 0, BORDER_DEFAULT);

Robotic & Vision Lab RoVis


Mat harris, sub, Ixy2, add, mx;
Mat elem = Mat::ones(4, 4, CV_32F);
subtract(Ix2.mul(Iy2), Ixy.mul(Ixy), sub);
cv::add(Ix2, Iy2, add);
//cv::add(add, eps, add);
add.mul(0.04);
cv::subtract(sub, add, harris);
cv::dilate(harris, mx, elem, Point(-1, -1), 1);
for (int i = 0; i <= img.rows - 1; i++)
{
for (int j = 0; j <= img.cols - 1; j++)
{
if (harris.at<float>(i, j) > 6000)
{
harris.at<float>(i, j) = 1;
circle(img, Point(i, j), 2, Scalar(255, 0, 0), CV_FILLED);
}
}
}
imshow("result", img);
waitKey(0);
destroyAllWindows();
return(0);

Robotic & Vision Lab RoVis


void cornerHarris(InputArray src, OutputArray dst, int blockSize, int ksize, double k, int
borderType=BORDER_DEFAULT ) Parameters:
src: hình đầu vào
dst: hình kết quả
blockSize: vùng quét
ksize: dien tích ma tận lọc sobel
k – Harris detector free parameter. See the formula below.
borderType – Pixel extrapolation method.

Robotic & Vision Lab RoVis


Mat src, gray;
// Load source image and convert it to gray
src = imread( "lena.jpg", 1 );
cvtColor( src, gray, CV_BGR2GRAY );
Mat dst, dst_norm, dst_norm_scaled;
dst = Mat::zeros( src.size(), CV_32FC1 );
cornerHarris( gray, dst, 7, 5, 0.05, BORDER_DEFAULT );
// Normalizing
normalize( dst, dst_norm, 0, 255, NORM_MINMAX, CV_32FC1, Mat() );
convertScaleAbs( dst_norm, dst_norm_scaled );
// Drawing a circle around corners
for( int j = 0; j < dst_norm.rows ; j++ )
{ for( int i = 0; i < dst_norm.cols; i++ )
{
if( (int) dst_norm.at<float>(j,i) > thresh )
{
circle( dst_norm_scaled, Point( i, j ), 5, Scalar(0), 2, 8, 0 );
}
}
}

Robotic & Vision Lab RoVis


Find interested point and matching

Robotic & Vision Lab RoVis

You might also like