mirror of https://github.com/opencv/opencv.git
commit
50bec53afc
40 changed files with 637 additions and 312 deletions
@ -0,0 +1,31 @@ |
||||
# https://editorconfig.org/ |
||||
|
||||
root = true |
||||
|
||||
[*] |
||||
end_of_line = lf |
||||
charset = utf-8 |
||||
trim_trailing_whitespace = true |
||||
insert_final_newline = true |
||||
indent_style = space |
||||
indent_size = 4 |
||||
|
||||
[{CMakeLists.*,*.cmake}] |
||||
indent_style = space |
||||
indent_size = 2 |
||||
|
||||
[Makefile] |
||||
indent_style = tab |
||||
|
||||
[*.{bat,cmd,cmd.*}] |
||||
end_of_line = crlf |
||||
indent_style = space |
||||
indent_size = 2 |
||||
|
||||
[*.{ps1,ps1.*}] |
||||
end_of_line = crlf |
||||
indent_style = space |
||||
indent_size = 4 |
||||
|
||||
[*.{md,markdown}] |
||||
indent_size = 2 |
After Width: | Height: | Size: 8.3 KiB |
After Width: | Height: | Size: 68 KiB |
After Width: | Height: | Size: 52 KiB |
After Width: | Height: | Size: 6.5 KiB |
@ -0,0 +1,61 @@ |
||||
Periodic Noise Removing Filter {#tutorial_periodic_noise_removing_filter} |
||||
========================== |
||||
|
||||
Goal |
||||
---- |
||||
|
||||
In this tutorial you will learn: |
||||
|
||||
- how to remove periodic noise in the Fourier domain |
||||
|
||||
Theory |
||||
------ |
||||
|
||||
@note The explanation is based on the book @cite gonzalez. The image on this page is a real world image. |
||||
|
||||
Periodic noise produces spikes in the Fourier domain that can often be detected by visual analysis. |
||||
|
||||
### How to remove periodic noise in the Fourier domain? |
||||
|
||||
Periodic noise can be reduced significantly via frequency domain filtering. On this page we use a notch reject filter with an appropriate radius to completely enclose the noise spikes in the Fourier domain. The notch filter rejects frequencies in predefined neighborhoods around a center frequency. The number of notch filters is arbitrary. The shape of the notch areas can also be arbitrary (e.g. rectangular or circular). On this page we use three circular shape notch reject filters. Power spectrum densify of an image is used for the noise spike’s visual detection. |
||||
|
||||
Source code |
||||
----------- |
||||
|
||||
You can find source code in the `samples/cpp/tutorial_code/ImgProc/periodic_noise_removing_filter/periodic_noise_removing_filter.cpp` of the OpenCV source code library. |
||||
|
||||
@include samples/cpp/tutorial_code/ImgProc/periodic_noise_removing_filter/periodic_noise_removing_filter.cpp |
||||
|
||||
Explanation |
||||
----------- |
||||
|
||||
Periodic noise reduction by frequency domain filtering consists of power spectrum density calculation (for the noise spikes visual detection), notch reject filter synthesis and frequency filtering: |
||||
@snippet samples/cpp/tutorial_code/ImgProc/periodic_noise_removing_filter/periodic_noise_removing_filter.cpp main |
||||
|
||||
A function calcPSD() calculates power spectrum density of an image: |
||||
@snippet samples/cpp/tutorial_code/ImgProc/periodic_noise_removing_filter/periodic_noise_removing_filter.cpp calcPSD |
||||
|
||||
A function synthesizeFilterH() forms a transfer function of an ideal circular shape notch reject filter according to a center frequency and a radius: |
||||
@snippet samples/cpp/tutorial_code/ImgProc/periodic_noise_removing_filter/periodic_noise_removing_filter.cpp synthesizeFilterH |
||||
|
||||
A function filter2DFreq() filters an image in the frequency domain. The functions fftshift() and filter2DFreq() are copied from the tutorial @ref tutorial_out_of_focus_deblur_filter "Out-of-focus Deblur Filter". |
||||
|
||||
Result |
||||
------ |
||||
|
||||
The figure below shows an image heavily corrupted by periodical noise of various frequencies. |
||||
![Image corrupted by periodic noise](images/period_input.jpg) |
||||
|
||||
The noise components are easily seen as bright dots (spikes) in the Power spectrum density shown in the figure below. |
||||
![Power spectrum density showing periodic noise](images/period_psd.jpg) |
||||
|
||||
The figure below shows a notch reject filter with an appropriate radius to completely enclose the noise spikes. |
||||
![Notch reject filter](images/period_filter.jpg) |
||||
|
||||
The result of processing the image with the notch reject filter is shown below. |
||||
![Result of filtering](images/period_output.jpg) |
||||
|
||||
The improvement is quite evident. This image contains significantly less visible periodic noise than the original image. |
||||
|
||||
You can also find a quick video demonstration of this filtering idea on [YouTube](https://youtu.be/Qne51TcWwAc). |
||||
@youtube{Qne51TcWwAc} |
@ -0,0 +1,106 @@ |
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
#include "perf_precomp.hpp" |
||||
|
||||
namespace opencv_test |
||||
{ |
||||
namespace |
||||
{ |
||||
|
||||
typedef ::perf::TestBaseWithParam< std::string > Perf_Objdetect_QRCode; |
||||
|
||||
PERF_TEST_P_(Perf_Objdetect_QRCode, detect) |
||||
{ |
||||
const std::string name_current_image = GetParam(); |
||||
const std::string root = "cv/qrcode/"; |
||||
|
||||
std::string image_path = findDataFile(root + name_current_image); |
||||
Mat src = imread(image_path, IMREAD_GRAYSCALE), straight_barcode; |
||||
ASSERT_FALSE(src.empty()) << "Can't read image: " << image_path; |
||||
|
||||
std::vector< Point > corners; |
||||
TEST_CYCLE() ASSERT_TRUE(detectQRCode(src, corners)); |
||||
SANITY_CHECK(corners); |
||||
} |
||||
|
||||
#ifdef HAVE_QUIRC |
||||
PERF_TEST_P_(Perf_Objdetect_QRCode, decode) |
||||
{ |
||||
const std::string name_current_image = GetParam(); |
||||
const std::string root = "cv/qrcode/"; |
||||
|
||||
std::string image_path = findDataFile(root + name_current_image); |
||||
Mat src = imread(image_path, IMREAD_GRAYSCALE), straight_barcode; |
||||
ASSERT_FALSE(src.empty()) << "Can't read image: " << image_path; |
||||
|
||||
std::vector< Point > corners; |
||||
std::string decoded_info; |
||||
ASSERT_TRUE(detectQRCode(src, corners)); |
||||
TEST_CYCLE() ASSERT_TRUE(decodeQRCode(src, corners, decoded_info, straight_barcode)); |
||||
|
||||
std::vector<uint8_t> decoded_info_uint8_t(decoded_info.begin(), decoded_info.end()); |
||||
SANITY_CHECK(decoded_info_uint8_t); |
||||
SANITY_CHECK(straight_barcode); |
||||
|
||||
} |
||||
#endif |
||||
|
||||
INSTANTIATE_TEST_CASE_P(/*nothing*/, Perf_Objdetect_QRCode, |
||||
::testing::Values( |
||||
"version_1_down.jpg", "version_1_left.jpg", "version_1_right.jpg", "version_1_up.jpg", "version_1_top.jpg", |
||||
"version_5_down.jpg", "version_5_left.jpg", "version_5_right.jpg", "version_5_up.jpg", "version_5_top.jpg", |
||||
"russian.jpg", "kanji.jpg", "link_github_ocv.jpg", "link_ocv.jpg", "link_wiki_cv.jpg" |
||||
) |
||||
); |
||||
|
||||
typedef ::perf::TestBaseWithParam< tuple< std::string, Size > > Perf_Objdetect_Not_QRCode; |
||||
|
||||
PERF_TEST_P_(Perf_Objdetect_Not_QRCode, detect) |
||||
{ |
||||
std::vector<Point> corners; |
||||
std::string type_gen = get<0>(GetParam()); |
||||
Size resolution = get<1>(GetParam()); |
||||
Mat not_qr_code(resolution, CV_8UC1, Scalar(0)); |
||||
if (type_gen == "random") |
||||
{ |
||||
RNG rng; |
||||
rng.fill(not_qr_code, RNG::UNIFORM, Scalar(0), Scalar(1)); |
||||
} |
||||
|
||||
TEST_CYCLE() ASSERT_FALSE(detectQRCode(not_qr_code, corners)); |
||||
SANITY_CHECK_NOTHING(); |
||||
} |
||||
|
||||
#ifdef HAVE_QUIRC |
||||
PERF_TEST_P_(Perf_Objdetect_Not_QRCode, decode) |
||||
{ |
||||
Mat straight_barcode; |
||||
std::string decoded_info; |
||||
std::vector< Point > corners; |
||||
corners.push_back(Point( 0, 0)); corners.push_back(Point( 0, 5)); |
||||
corners.push_back(Point(10, 0)); corners.push_back(Point(15, 15)); |
||||
|
||||
std::string type_gen = get<0>(GetParam()); |
||||
Size resolution = get<1>(GetParam()); |
||||
Mat not_qr_code(resolution, CV_8UC1, Scalar(0)); |
||||
if (type_gen == "random") |
||||
{ |
||||
RNG rng; |
||||
rng.fill(not_qr_code, RNG::UNIFORM, Scalar(0), Scalar(1)); |
||||
} |
||||
|
||||
TEST_CYCLE() ASSERT_FALSE(decodeQRCode(not_qr_code, corners, decoded_info, straight_barcode)); |
||||
SANITY_CHECK_NOTHING(); |
||||
} |
||||
#endif |
||||
|
||||
INSTANTIATE_TEST_CASE_P(/*nothing*/, Perf_Objdetect_Not_QRCode, |
||||
::testing::Combine( |
||||
::testing::Values("zero", "random"), |
||||
::testing::Values(Size(640, 480), Size(1280, 720), Size(1920, 1080)) |
||||
)); |
||||
|
||||
} |
||||
} // namespace
|
Loading…
Reference in new issue