 |
OpenCV
3.2.0
Open Source Computer Vision
|
.2.0+dfsg_doc_tutorials_imgproc_imgtrans_distance_transformation_distance_transform
Goal
In this tutorial you will learn how to:
- Use the OpenCV function cv::filter2D in order to perform some laplacian filtering for image sharpening
- Use the OpenCV function cv::distanceTransform in order to obtain the derived representation of a binary image, where the value of each pixel is replaced by its distance to the nearest background pixel
- Use the OpenCV function cv::watershed in order to isolate objects in the image from the background
Theory
Code
This tutorial code's is shown lines below. You can also download it from here.
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
int main(int, char** argv)
{
return -1;
for(
int x = 0; x < src.
rows; x++ ) {
for(
int y = 0; y < src.
cols; y++ ) {
}
}
}
imshow(
"Black Background Image", src);
1, 1, 1,
1, -8, 1,
1, 1, 1);
Mat imgResult = sharp - imgLaplacian;
imgLaplacian.convertTo(imgLaplacian,
CV_8UC3);
imshow(
"New Sharped Image", imgResult );
src = imgResult;
imshow(
"Distance Transform Image", dist);
vector<vector<Point> > contours;
for (
size_t i = 0;
i < contours.size();
i++)
drawContours(markers, contours,
static_cast<int>(
i), Scalar::all(
static_cast<int>(
i)+1), -1);
imshow(
"Markers", markers*10000);
vector<Vec3b> colors;
for (
size_t i = 0;
i < contours.size();
i++)
{
}
for (
int i = 0;
i < markers.
rows;
i++)
{
for (
int j = 0; j < markers.
cols; j++)
{
if (
index > 0 &&
index <=
static_cast<int>(contours.size()))
else
}
}
return 0;
}
Explanation / Result
- Load the source image and check if it is loaded without any problem, then show it:
if (!src.data)
return -1;
- Then if we have an image with white background, it is good to tranform it black. This will help us to desciminate the foreground objects easier when we will apply the Distance Transform:
for( int x = 0; x < src.rows; x++ ) {
for(
int y = 0; y < src.
cols; y++ ) {
if ( src.at<
Vec3b>(x, y) ==
Vec3b(255,255,255) ) {
src.at<
Vec3b>(x, y)[0] = 0;
src.at<
Vec3b>(x, y)[1] = 0;
src.at<
Vec3b>(x, y)[2] = 0;
}
}
}
imshow(
"Black Background Image", src);
Afterwards we will sharp our image in order to acute the edges of the foreground objects. We will apply a laplacian filter with a quite strong filter (an approximation of second derivative):
Mat kernel = (Mat_<float>(3,3) <<
1, 1, 1,
1, -8, 1,
1, 1, 1);
Mat imgLaplacian;
Mat sharp = src;
Mat imgResult = sharp - imgLaplacian;
imgLaplacian.convertTo(imgLaplacian,
CV_8UC3);
imshow(
"New Sharped Image", imgResult );
- Now we tranfrom our new sharped source image to a grayscale and a binary one, respectively:
- We are ready now to apply the Distance Tranform on the binary image. Moreover, we normalize the output image in order to be able visualize and threshold the result:
Mat dist;
imshow(
"Distance Transform Image", dist);
- We threshold the dist image and then perform some morphology operation (i.e. dilation) in order to extract the peaks from the above image:
Mat kernel1 = Mat::ones(3, 3,
CV_8UC1);
- From each blob then we create a seed/marker for the watershed algorithm with the help of the cv::findContours function:
Mat dist_8u;
vector<vector<Point> > contours;
Mat markers = Mat::zeros(dist.size(),
CV_32SC1);
for (
size_t i = 0;
i < contours.size();
i++)
drawContours(markers, contours,
static_cast<int>(
i), Scalar::all(
static_cast<int>(
i)+1), -1);
imshow(
"Markers", markers*10000);
- Finally, we can apply the watershed algorithm, and visualize the result:
Mat mark = Mat::zeros(markers.size(),
CV_8UC1);
vector<Vec3b> colors;
for (
size_t i = 0;
i < contours.size();
i++)
{
}
Mat dst = Mat::zeros(markers.size(),
CV_8UC3);
for (
int i = 0;
i < markers.rows;
i++)
{
for (int j = 0; j < markers.cols; j++)
{
int index = markers.at<
int>(
i,j);
if (
index > 0 &&
index <=
static_cast<int>(contours.size()))
else
}
}
int uniform(int a, int b)
returns uniformly distributed integer random number from [a,b) range
Vec< uchar, 3 > Vec3b
Definition: matx.hpp:364
int rows
the number of rows and columns or (-1, -1) when the matrix has more than 2 dimensions
Definition: mat.hpp:1959
void watershed(InputArray image, InputOutputArray markers)
Performs a marker-based image segmentation using the watershed algorithm.
void filter2D(InputArray src, OutputArray dst, int ddepth, InputArray kernel, Point anchor=Point(-1,-1), double delta=0, int borderType=BORDER_DEFAULT)
Convolves an image with the kernel.
RNG & theRNG()
Returns the default random number generator.
@ NORM_MINMAX
flag
Definition: base.hpp:196
void cvtColor(InputArray src, OutputArray dst, int code, int dstCn=0)
Converts an image from one color space to another.
void distanceTransform(InputArray src, OutputArray dst, OutputArray labels, int distanceType, int maskSize, int labelType=DIST_LABEL_CCOMP)
Calculates the distance to the closest zero pixel for each pixel of the source image.
_Tp & at(int i0=0)
Returns a reference to the specified array element.
double threshold(InputArray src, OutputArray dst, double thresh, double maxval, int type)
Applies a fixed-level threshold to each array element.
int waitKey(int delay=0)
Waits for a pressed key.
@ CV_BGR2GRAY
Definition: types_c.h:121
@ CV_CHAIN_APPROX_SIMPLE
Definition: types_c.h:458
#define CV_8U
Definition: interface.h:67
#define CV_32SC1
Definition: interface.h:106
@ CV_THRESH_BINARY
Definition: types_c.h:571
void convertTo(OutputArray m, int rtype, double alpha=1, double beta=0) const
Converts an array to another data type with optional scaling.
#define CV_32F
Definition: interface.h:72
void dilate(InputArray src, OutputArray dst, InputArray kernel, Point anchor=Point(-1,-1), int iterations=1, int borderType=BORDER_CONSTANT, const Scalar &borderValue=morphologyDefaultBorderValue())
Dilates an image by using a specific structuring element.
Mat imread(const String &filename, int flags=IMREAD_COLOR)
Loads an image from a file.
Template class for short numerical vectors, a partial case of Matx.
Definition: matx.hpp:306
int cols
Definition: mat.hpp:1959
#define CV_8UC3
Definition: interface.h:84
@ CV_RETR_EXTERNAL
Definition: types_c.h:446
MatSize size
Definition: mat.hpp:1978
unsigned char uchar
Definition: interface.h:47
#define CV_RGB(r, g, b)
Definition: imgproc_c.h:985
void imshow(const String &winname, InputArray mat)
Displays an image in the specified window.
void drawContours(InputOutputArray image, InputArrayOfArrays contours, int contourIdx, const Scalar &color, int thickness=1, int lineType=LINE_8, InputArray hierarchy=noArray(), int maxLevel=INT_MAX, Point offset=Point())
Draws contours outlines or filled contours.
Point2i Point
Definition: types.hpp:183
@ index
Definition: gr_skig.hpp:77
n-dimensional dense array class
Definition: mat.hpp:741
@ cols
Definition: matx.hpp:92
for i
Definition: modelConvert.m:63
@ CV_DIST_L2
Definition: types_c.h:559
#define CV_8UC1
Definition: interface.h:82
Definition: affine.hpp:52
void bitwise_not(InputArray src, OutputArray dst, InputArray mask=noArray())
Inverts every bit of an array.
void findContours(InputOutputArray image, OutputArrayOfArrays contours, OutputArray hierarchy, int mode, int method, Point offset=Point())
Finds contours in a binary image.
static Vec< _Tp, cn > normalize(const Vec< _Tp, cn > &v)
@ circle
Definition: gr_skig.hpp:62
uchar * data
pointer to the data
Definition: mat.hpp:1961
@ CV_THRESH_OTSU
Definition: types_c.h:577