#include <iostream>
#include "opencv2/opencv.hpp"

void make_salt_and_pepper_noise(cv::Mat& dst, float percent) {
	int num = dst.total() * percent;
	for (int i = 0; i < num; i++) {
		dst.at<uchar>(rand() % dst.rows, rand() % dst.cols) = (i % 2) * 255;
	}
}

int main() {
	cv::VideoCapture camera(0);
	if (!camera.isOpened()) {
		std::cerr << "isOpened()" << std::endl;
		return EXIT_FAILURE;
	}
	std::uint32_t fps = camera.get(cv::CAP_PROP_FPS);
	cv::Mat src;

	while (cv::waitKey(1000 / fps) != 27) {
		camera >> src;
		if (src.empty()) break;
		cv::imshow("preview", src);
	}
	cv::cvtColor(src, src, cv::COLOR_BGR2GRAY);

	cv::Mat gaussian_noise(src.size(), CV_8UC1);
	//cv::Mat gaussian, salt_and_pepper, bilateral, median;

	cv::randn(gaussian_noise, 0, 5);
	cv::Mat gaussian = src + gaussian_noise;

	cv::Mat salt_and_pepper;
	src.copyTo(salt_and_pepper);
	make_salt_and_pepper_noise(salt_and_pepper, 0.1);

	cv::Mat bilateral;
	cv::bilateralFilter(gaussian, bilateral, -1, 10, 5);

	cv::Mat median;
	cv::medianBlur(salt_and_pepper, median, 3);

	cv::imshow("src", src);
	cv::imshow("gaussian", gaussian);
	cv::imshow("salt_and_pepper", salt_and_pepper);
	cv::imshow("bilateral", bilateral);
	cv::imshow("median", median);

	cv::waitKey();
	cv::destroyAllWindows();
}