【Opencv测试用例(一)】


Chapter01

1、mat.cpp

结果

在这里插入图片描述

测试代码


#include <iostream>
#include<string>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>

// test function that creates an image
static cv::Mat function() {

   // create image
   cv::Mat ima(500,500,CV_8U,50);
   // return it
   return ima;
}

static void test()
{
	// create a new image made of 240 rows and 320 columns
	cv::Mat image1(240, 320, CV_8U, 100);
	// or:
	// cv::Mat image1(240,320,CV_8U,cv::Scalar(100));

	cv::imshow("Image", image1); // show the image
	cv::waitKey(0); // wait for a key pressed

	// re-allocate a new image
	// (only if size or type are different)
	image1.create(200, 200, CV_8U);
	image1 = 200;

	cv::imshow("Image", image1); // show the image
	cv::waitKey(0); // wait for a key pressed

	// create a red color image
	// channel order is BGR
	cv::Mat image2(240, 320, CV_8UC3, cv::Scalar(0, 0, 255));

	// or:
	// cv::Mat image2(cv::Size(320,240),CV_8UC3);
	// image2= cv::Scalar(0,0,255);

	cv::imshow("Image", image2); // show the image
	cv::waitKey(0); // wait for a key pressed

	// read an image
	std::string path_puppy = "F:/images/puppy.bmp";
	cv::Mat image3 = cv::imread(path_puppy);

	// all these images point to the same data block
	cv::Mat image4(image3);
	image1 = image3;

	// these images are new copies of the source image
	image3.copyTo(image2);
	cv::Mat image5 = image3.clone();

	// transform the image for testing
	cv::flip(image3, image3, 1);

	// check which images have been affected by the processing
	cv::imshow("Image 3", image3);
	cv::imshow("Image 1", image1);
	cv::imshow("Image 2", image2);
	cv::imshow("Image 4", image4);
	cv::imshow("Image 5", image5);
	cv::waitKey(0); // wait for a key pressed

	// get a gray-level image from a function
	cv::Mat gray = function();

	cv::imshow("Image", gray); // show the image
	cv::waitKey(0); // wait for a key pressed

	// read the image in gray scale
	image1 = cv::imread(path_puppy, cv::IMREAD_GRAYSCALE);

	// convert the image into a floating point image [0,1]
	image1.convertTo(image2, CV_32F, 1 / 255.0, 0.0);

	cv::imshow("Image", image2); // show the image

	// Test cv::Matx
	// a 3x3 matrix of double-precision
	cv::Matx33d matrix(3.0, 2.0, 1.0,
		2.0, 1.0, 3.0,
		1.0, 2.0, 3.0);
	// a 3x1 matrix (a vector)
	cv::Matx31d vector(5.0, 1.0, 3.0);
	// multiplication
	cv::Matx31d result = matrix * vector;

	std::cout << result;
	cv::waitKey(0); // wait for a key pressed
}

int main() {
	test();
	system("pause");
	return 0;
}

2、logo.cpp

结果

在这里插入图片描述

测试代码


#include <iostream>
#include  <string>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
using namespace std;
static void test() {
	// define an image window
	cv::namedWindow("Image"); 
	// read the image 
	string path_puppy = "F:/images/puppy.bmp";
	cv::Mat image=  cv::imread(path_puppy);
	string path_smalllogo = "F:/images/smalllogo.png";
	// read the logo
	cv::Mat logo=  cv::imread(path_smalllogo);
	// define image ROI at image bottom-right
	cv::Mat imageROI(image, 
		          cv::Rect(image.cols-logo.cols, //ROI coordinates
                           image.rows-logo.rows,
		                   logo.cols,logo.rows));// ROI size
	// insert logo
	logo.copyTo(imageROI);
	cv::imshow("Image", image); // show the image
	cv::waitKey(0); // wait for a key pressed
	// re-read the original image
	image=  cv::imread(path_puppy);
	// define image ROI at image bottom-right
	imageROI= image(cv::Rect(image.cols-logo.cols,image.rows-logo.rows,
		                     logo.cols,logo.rows));
	// or using ranges:
    // imageROI= image(cv::Range(image.rows-logo.rows,image.rows), 
    //                 cv::Range(image.cols-logo.cols,image.cols));

    // use the logo as a mask (must be gray-level)
    cv::Mat mask(logo);
	// insert by copying only at locations of non-zero mask
	logo.copyTo(imageROI,mask);
	cv::imshow("Image", image); // show the image
	cv::waitKey(0); // wait for a key pressed
}

int main() 
{
	test();
	system("pause");
	return 0;
}

3、loadDiaplaySave.cpp

结果

在这里插入图片描述

测试代码


#include <iostream>
#include <string>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
using namespace std;

static void onMouse( int event, int x, int y, int flags, void* param)	{
	
	cv::Mat *im= reinterpret_cast<cv::Mat*>(param);

    switch (event) {	// dispatch the event

		case cv::EVENT_LBUTTONDOWN: // mouse button down event

			// display pixel value at (x,y)
			std::cout << "at (" << x << "," << y << ") value is: " 
				      << static_cast<int>(im->at<uchar>(cv::Point(x,y))) << std::endl;
			break;
	}
}

static void test() {

	cv::Mat image; // create an empty image
	std::cout << "This image is " << image.rows << " x " 
              << image.cols << std::endl;

	// read the input image as a gray-scale image
	string path_puppy = "F:/images/puppy.bmp";
	image=  cv::imread(path_puppy, cv::IMREAD_GRAYSCALE);

    if (image.empty()) {  // error handling
        // no image has been created...
		// possibly display an error message
		// and quit the application 
		std::cout << "Error reading image..." << std::endl;
		return ;
	}

	std::cout << "This image is " << image.rows << " x " 
			  << image.cols << std::endl;
	std::cout << "This image has " 
              << image.channels() << " channel(s)" << std::endl; 

	// create image window named "My Image"
    cv::namedWindow("Original Image"); // define the window (optional)
	cv::imshow("Original Image", image); // show the image

	// set the mouse callback for this image
	cv::setMouseCallback("Original Image", onMouse, reinterpret_cast<void*>(&image));

	cv::Mat result; // we create another empty image
	cv::flip(image,result,1); // positive for horizontal
                          // 0 for vertical,                     
                          // negative for both

	cv::namedWindow("Output Image"); // the output window
	cv::imshow("Output Image", result);

	cv::waitKey(0); // 0 to indefinitely wait for a key pressed
                // specifying a positive value will wait for
                // the given amount of msec
	string path_output = "F:/images/puppy.bmp";
	cv::imwrite(path_output, result); // save result
	
	// create another image window named
	cv::namedWindow("Drawing on an Image"); // define the window

	cv::circle(image,              // destination image 
		       cv::Point(155,110), // center coordinate
			   65,                 // radius  
			   0,                  // color (here black)
			   3);                 // thickness
	
	cv::putText(image,                   // destination image
		        "This is a dog.",        // text
				cv::Point(40,200),       // text position
				cv::FONT_HERSHEY_PLAIN,  // font type
				2.0,                     // font scale
				255,                     // text color (here white)
				2);                      // text thickness

	cv::imshow("Drawing on an Image", image); // show the image
	cv::waitKey(0); // 0 to indefinitely wait for a key pressed
}

int main()
{
	test();
	system("pause");
	return 0;
}

Chapter02

1、addImages.cpp

结果

在这里插入图片描述

测试代码

#include <vector>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include<string>
using namespace std;
static void test()
{
	cv::Mat image1;
	cv::Mat image2;

	// open images
	string path_boldt = "F:/images/boldt.jpg";
	image1= cv::imread(path_boldt);
	string path_rain = "F:/images/rain.jpg";
	image2= cv::imread(path_rain);
	if (!image1.data)
		return ; 
	if (!image2.data)
		return ; 

	cv::namedWindow("Image 1");
	cv::imshow("Image 1",image1);
	cv::namedWindow("Image 2");
	cv::imshow("Image 2",image2);

	cv::Mat result;
	// add two images
	cv::addWeighted(image1,0.7,image2,0.9,0.,result);

	cv::namedWindow("result");
	cv::imshow("result",result);

	// using overloaded operator
	result= 0.7*image1+0.9*image2;

	cv::namedWindow("result with operators");
	cv::imshow("result with operators",result);

	image2= cv::imread(path_rain,0);

	// create vector of 3 images
	std::vector<cv::Mat> planes;
	// split 1 3-channel image into 3 1-channel images
	cv::split(image1,planes);
	// add to blue channel
	planes[0]+= image2;
	// merge the 3 1-channel images into 1 3-channel image
	cv::merge(planes,result);

	cv::namedWindow("Result on blue channel");
	cv::imshow("Result on blue channel",result);
	cv::waitKey();

}

int main()
{
	test();
	system("pause");
	return 0;
}

2、colorReduce.cpp

结果

在这里插入图片描述

测试代码

#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
// 1st version
// see recipe Scanning an image with pointers
static void colorReduce(cv::Mat image, int div = 64) {
	int nl = image.rows; // number of lines
	int nc = image.cols * image.channels(); // total number of elements per line
	for (int j = 0; j < nl; j++) {
		// get the address of row j
		uchar* data = image.ptr<uchar>(j);
		for (int i = 0; i < nc; i++) {

			// process each pixel ---------------------

			data[i] = data[i] / div * div + div / 2;

			// end of pixel processing ----------------

		} // end of line
	}
}

// version with input/ouput images
// see recipe Scanning an image with pointers
static void colorReduceIO(const cv::Mat &image, // input image
	cv::Mat &result,      // output image
	int div = 64) {

	int nl = image.rows; // number of lines
	int nc = image.cols; // number of columns
	int nchannels = image.channels(); // number of channels

	// allocate output image if necessary
	result.create(image.rows, image.cols, image.type());

	for (int j = 0; j < nl; j++) {

		// get the addresses of input and output row j
		const uchar* data_in = image.ptr<uchar>(j);
		uchar* data_out = result.ptr<uchar>(j);

		for (int i = 0; i < nc*nchannels; i++) {

			// process each pixel ---------------------

			data_out[i] = data_in[i] / div * div + div / 2;

			// end of pixel processing ----------------

		} // end of line
	}
}

// Test 1
// this version uses the dereference operator *
static void colorReduce1(cv::Mat image, int div = 64) {

	int nl = image.rows; // number of lines
	int nc = image.cols * image.channels(); // total number of elements per line
	uchar div2 = div >> 1; // div2 = div/2

	for (int j = 0; j < nl; j++) {

		uchar* data = image.ptr<uchar>(j);

		for (int i = 0; i < nc; i++) {


			// process each pixel ---------------------

			*data++ = *data / div * div + div2;

			// end of pixel processing ----------------

		} // end of line
	}
}

// Test 2
// this version uses the modulo operator
static void colorReduce2(cv::Mat image, int div = 64) {

	int nl = image.rows; // number of lines
	int nc = image.cols * image.channels(); // total number of elements per line
	uchar div2 = div >> 1; // div2 = div/2

	for (int j = 0; j < nl; j++) {

		uchar* data = image.ptr<uchar>(j);

		for (int i = 0; i < nc; i++) {

			// process each pixel ---------------------

			int v = *data;
			*data++ = v - v % div + div2;

			// end of pixel processing ----------------

		} // end of line
	}
}

// Test 3
// this version uses a binary mask
static void colorReduce3(cv::Mat image, int div = 64) {

	int nl = image.rows; // number of lines
	int nc = image.cols * image.channels(); // total number of elements per line
	int n = static_cast<int>(log(static_cast<double>(div)) / log(2.0) + 0.5);
	// mask used to round the pixel value
	uchar mask = 0xFF << n; // e.g. for div=16, mask= 0xF0
	uchar div2 = 1 << (n - 1); // div2 = div/2

	for (int j = 0; j < nl; j++) {

		uchar* data = image.ptr<uchar>(j);

		for (int i = 0; i < nc; i++) {

			// process each pixel ---------------------

			*data &= mask;     // masking
			*data++ |= div2;   // add div/2

		  // end of pixel processing ----------------

		} // end of line
	}
}


// Test 4
// this version uses direct pointer arithmetic with a binary mask
static void colorReduce4(cv::Mat image, int div = 64) {

	int nl = image.rows; // number of lines
	int nc = image.cols * image.channels(); // total number of elements per line
	int n = static_cast<int>(log(static_cast<double>(div)) / log(2.0) + 0.5);
	int step = image.step; // effective width
	// mask used to round the pixel value
	uchar mask = 0xFF << n; // e.g. for div=16, mask= 0xF0
	uchar div2 = div >> 1; // div2 = div/2

	// get the pointer to the image buffer
	uchar *data = image.data;

	for (int j = 0; j < nl; j++) {

		for (int i = 0; i < nc; i++) {

			// process each pixel ---------------------

			*(data + i) &= mask;
			*(data + i) += div2;

			// end of pixel processing ----------------

		} // end of line

		data += step;  // next line
	}
}

// Test 5
// this version recomputes row size each time
static void colorReduce5(cv::Mat image, int div = 64) {

	int nl = image.rows; // number of lines
	int n = static_cast<int>(log(static_cast<double>(div)) / log(2.0) + 0.5);
	// mask used to round the pixel value
	uchar mask = 0xFF << n; // e.g. for div=16, mask= 0xF0

	for (int j = 0; j < nl; j++) {

		uchar* data = image.ptr<uchar>(j);

		for (int i = 0; i < image.cols * image.channels(); i++) {

			// process each pixel ---------------------

			*data &= mask;
			*data++ += div / 2;

			// end of pixel processing ----------------

		} // end of line
	}
}

// Test 6
// this version optimizes the case of continuous image
static void colorReduce6(cv::Mat image, int div = 64) {

	int nl = image.rows; // number of lines
	int nc = image.cols * image.channels(); // total number of elements per line

	if (image.isContinuous()) {
		// then no padded pixels
		nc = nc * nl;
		nl = 1;  // it is now a 1D array
	}

	int n = static_cast<int>(log(static_cast<double>(div)) / log(2.0) + 0.5);
	// mask used to round the pixel value
	uchar mask = 0xFF << n; // e.g. for div=16, mask= 0xF0
	uchar div2 = div >> 1; // div2 = div/2

   // this loop is executed only once
   // in case of continuous images
	for (int j = 0; j < nl; j++) {

		uchar* data = image.ptr<uchar>(j);

		for (int i = 0; i < nc; i++) {

			// process each pixel ---------------------

			*data &= mask;
			*data++ += div2;

			// end of pixel processing ----------------

		} // end of line
	}
}

// Test 7
// this versions applies reshape on continuous image
static void colorReduce7(cv::Mat image, int div = 64) {

	if (image.isContinuous()) {
		// no padded pixels
		image.reshape(1,   // new number of channels
			1); // new number of rows
	}
	// number of columns set accordingly

	int nl = image.rows; // number of lines
	int nc = image.cols*image.channels(); // number of columns

	int n = static_cast<int>(log(static_cast<double>(div)) / log(2.0) + 0.5);
	// mask used to round the pixel value
	uchar mask = 0xFF << n; // e.g. for div=16, mask= 0xF0
	uchar div2 = div >> 1; // div2 = div/2

	for (int j = 0; j < nl; j++) {

		uchar* data = image.ptr<uchar>(j);

		for (int i = 0; i < nc; i++) {

			// process each pixel ---------------------

			*data &= mask;
			*data++ += div2;

			// end of pixel processing ----------------

		} // end of line
	}
}

// Test 8
// this version processes the 3 channels inside the loop with Mat_ iterators
static void colorReduce8(cv::Mat image, int div = 64) {

	// get iterators
	cv::Mat_<cv::Vec3b>::iterator it = image.begin<cv::Vec3b>();
	cv::Mat_<cv::Vec3b>::iterator itend = image.end<cv::Vec3b>();
	uchar div2 = div >> 1; // div2 = div/2

	for (; it != itend; ++it) {

		// process each pixel ---------------------

		(*it)[0] = (*it)[0] / div * div + div2;
		(*it)[1] = (*it)[1] / div * div + div2;
		(*it)[2] = (*it)[2] / div * div + div2;

		// end of pixel processing ----------------
	}
}

// Test 9
// this version uses iterators on Vec3b
static void colorReduce9(cv::Mat image, int div = 64) {

	// get iterators
	cv::MatIterator_<cv::Vec3b> it = image.begin<cv::Vec3b>();
	cv::MatIterator_<cv::Vec3b> itend = image.end<cv::Vec3b>();

	const cv::Vec3b offset(div / 2, div / 2, div / 2);

	for (; it != itend; ++it) {

		// process each pixel ---------------------

		*it = *it / div * div + offset;
		// end of pixel processing ----------------
	}
}

// Test 10
// this version uses iterators with a binary mask
static void colorReduce10(cv::Mat image, int div = 64) {

	// div must be a power of 2
	int n = static_cast<int>(log(static_cast<double>(div)) / log(2.0) + 0.5);
	// mask used to round the pixel value
	uchar mask = 0xFF << n; // e.g. for div=16, mask= 0xF0
	uchar div2 = div >> 1; // div2 = div/2

	// get iterators
	cv::Mat_<cv::Vec3b>::iterator it = image.begin<cv::Vec3b>();
	cv::Mat_<cv::Vec3b>::iterator itend = image.end<cv::Vec3b>();

	// scan all pixels
	for (; it != itend; ++it) {

		// process each pixel ---------------------

		(*it)[0] &= mask;
		(*it)[0] += div2;
		(*it)[1] &= mask;
		(*it)[1] += div2;
		(*it)[2] &= mask;
		(*it)[2] += div2;

		// end of pixel processing ----------------
	}
}

// Test 11
// this versions uses ierators from Mat_ 
static void colorReduce11(cv::Mat image, int div = 64) {

	// get iterators
	cv::Mat_<cv::Vec3b> cimage = image;
	cv::Mat_<cv::Vec3b>::iterator it = cimage.begin();
	cv::Mat_<cv::Vec3b>::iterator itend = cimage.end();
	uchar div2 = div >> 1; // div2 = div/2

	for (; it != itend; it++) {

		// process each pixel ---------------------

		(*it)[0] = (*it)[0] / div * div + div2;
		(*it)[1] = (*it)[1] / div * div + div2;
		(*it)[2] = (*it)[2] / div * div + div2;

		// end of pixel processing ----------------
	}
}


// Test 12
// this version uses the at method
static void colorReduce12(cv::Mat image, int div = 64) {

	int nl = image.rows; // number of lines
	int nc = image.cols; // number of columns
	uchar div2 = div >> 1; // div2 = div/2

	for (int j = 0; j < nl; j++) {
		for (int i = 0; i < nc; i++) {

			// process each pixel ---------------------

			image.at<cv::Vec3b>(j, i)[0] = image.at<cv::Vec3b>(j, i)[0] / div * div + div2;
			image.at<cv::Vec3b>(j, i)[1] = image.at<cv::Vec3b>(j, i)[1] / div * div + div2;
			image.at<cv::Vec3b>(j, i)[2] = image.at<cv::Vec3b>(j, i)[2] / div * div + div2;

			// end of pixel processing ----------------

		} // end of line
	}
}


// Test 13
// this version uses Mat overloaded operators
static void colorReduce13(cv::Mat image, int div = 64) {
	int n = static_cast<int>(log(static_cast<double>(div)) / log(2.0) + 0.5);
	// mask used to round the pixel value
	uchar mask = 0xFF << n; // e.g. for div=16, mask= 0xF0
	// perform color reduction
	image = (image&cv::Scalar(mask, mask, mask)) + cv::Scalar(div / 2, div / 2, div / 2);
}

// Test 14
// this version uses a look up table
static void colorReduce14(cv::Mat image, int div = 64) {

	cv::Mat lookup(1, 256, CV_8U);

	for (int i = 0; i < 256; i++) {

		lookup.at<uchar>(i) = i / div * div + div / 2;
	}
	cv::LUT(image, lookup, image);
}

#define NTESTS 15
#define NITERATIONS 10

static int test()
{
	// read the image
	std::string path_boldt = "F:/images/boldt.jpg";
	cv::Mat image = cv::imread(path_boldt);
	// time and process the image
	const int64 start = cv::getTickCount();
	colorReduce(image, 64);
	//Elapsed time in seconds
	double duration = (cv::getTickCount() - start) / cv::getTickFrequency();
	// display the image
	std::cout << "Duration= " << duration << "secs" << std::endl;
	cv::namedWindow("Image");
	cv::imshow("Image", image);
	cv::waitKey();
	// test different versions of the function
	int64 t[NTESTS], tinit;
	// timer values set to 0
	for (int i = 0; i < NTESTS; i++)
		t[i] = 0;
	cv::Mat images[NTESTS];
	cv::Mat result;
	// the versions to be tested
	typedef void(*FunctionPointer)(cv::Mat, int);
	FunctionPointer functions[NTESTS] = { colorReduce, colorReduce1, colorReduce2, colorReduce3, colorReduce4,
										  colorReduce5, colorReduce6, colorReduce7, colorReduce8, colorReduce9,
										  colorReduce10, colorReduce11, colorReduce12, colorReduce13, colorReduce14 };
	// repeat the tests several times
	int n = NITERATIONS;
	for (int k = 0; k < n; k++) {

		std::cout << k << " of " << n << std::endl;

		// test each version
		for (int c = 0; c < NTESTS; c++) {

			images[c] = cv::imread(path_boldt);

			// set timer and call function
			tinit = cv::getTickCount();
			functions[c](images[c], 64);
			t[c] += cv::getTickCount() - tinit;

			std::cout << ".";
		}

		std::cout << std::endl;
	}
	// short description of each function
	std::string descriptions[NTESTS] = {
		"original version:",
		"with dereference operator:",
		"using modulo operator:",
		"using a binary mask:",
		"direct ptr arithmetic:",
		"row size recomputation:",
		"continuous image:",
		"reshape continuous image:",
		"with iterators:",
		"Vec3b iterators:",
		"iterators and mask:",
		"iterators from Mat_:",
		"at method:",
		"overloaded operators:",
		"look-up table:",
	};

	for (int i = 0; i < NTESTS; i++) {
		cv::namedWindow(descriptions[i]);
		cv::imshow(descriptions[i], images[i]);
	}
	// print average execution time
	std::cout << std::endl << "-------------------------------------------" << std::endl << std::endl;
	for (int i = 0; i < NTESTS; i++) {

		std::cout << i << ". " << descriptions[i] << 1000.*t[i] / cv::getTickFrequency() / n << "ms" << std::endl;
	}
	cv::waitKey();
	return 0;
}

int main()
{
	test();
	system("pause");
	return 0;
}

3、contrast.cpp

结果

在这里插入图片描述

测试代码


#include <iostream>

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
void sharpen(const cv::Mat &image, cv::Mat &result) {

	result.create(image.size(), image.type()); // allocate if necessary
	int nchannels = image.channels();

	for (int j = 1; j < image.rows - 1; j++) { // for all rows (except first and last)

		const uchar* previous = image.ptr<const uchar>(j - 1); // previous row
		const uchar* current = image.ptr<const uchar>(j);	// current row
		const uchar* next = image.ptr<const uchar>(j + 1);		// next row

		uchar* output = result.ptr<uchar>(j);	// output row

		for (int i = nchannels; i < (image.cols - 1)*nchannels; i++) {

			// apply sharpening operator
			*output++ = cv::saturate_cast<uchar>(5 * current[i] - current[i - nchannels] - current[i + nchannels] - previous[i] - next[i]);
		}
	}

	// Set the unprocess pixels to 0
	result.row(0).setTo(cv::Scalar(0));
	result.row(result.rows - 1).setTo(cv::Scalar(0));
	result.col(0).setTo(cv::Scalar(0));
	result.col(result.cols - 1).setTo(cv::Scalar(0));
}

// same function but using iterator
// this one works only for gray-level image
static void sharpenIterator(const cv::Mat &image, cv::Mat &result) {

	// must be a gray-level image
	CV_Assert(image.type() == CV_8UC1);

	// initialize iterators at row 1
	cv::Mat_<uchar>::const_iterator it = image.begin<uchar>() + image.cols;
	cv::Mat_<uchar>::const_iterator itend = image.end<uchar>() - image.cols;
	cv::Mat_<uchar>::const_iterator itup = image.begin<uchar>();
	cv::Mat_<uchar>::const_iterator itdown = image.begin<uchar>() + 2 * image.cols;

	// setup output image and iterator
	result.create(image.size(), image.type()); // allocate if necessary
	cv::Mat_<uchar>::iterator itout = result.begin<uchar>() + result.cols;

	for (; it != itend; ++it, ++itout, ++itup, ++itdown) {

		*itout = cv::saturate_cast<uchar>(*it * 5 - *(it - 1) - *(it + 1) - *itup - *itdown);
	}

	// Set the unprocessed pixels to 0
	result.row(0).setTo(cv::Scalar(0));
	result.row(result.rows - 1).setTo(cv::Scalar(0));
	result.col(0).setTo(cv::Scalar(0));
	result.col(result.cols - 1).setTo(cv::Scalar(0));
}

// using kernel
void sharpen2D(const cv::Mat &image, cv::Mat &result) {

	// Construct kernel (all entries initialized to 0)
	cv::Mat kernel(3, 3, CV_32F, cv::Scalar(0));
	// assigns kernel values
	kernel.at<float>(1, 1) = 5.0;
	kernel.at<float>(0, 1) = -1.0;
	kernel.at<float>(2, 1) = -1.0;
	kernel.at<float>(1, 0) = -1.0;
	kernel.at<float>(1, 2) = -1.0;

	//filter the image
	cv::filter2D(image, result, image.depth(), kernel);
}

static int test()
{
	// test sharpen function
	std::string path_boldt = "F:/images/boldt.jpg";
	cv::Mat image = cv::imread(path_boldt);
	if (!image.data)
		return 0;

	cv::Mat result;

	double time = static_cast<double>(cv::getTickCount());
	sharpen(image, result);
	time = (static_cast<double>(cv::getTickCount()) - time) / cv::getTickFrequency();
	std::cout << "time= " << time << std::endl;

	cv::namedWindow("Image");
	cv::imshow("Image", result);

	// test sharpenIterator

	// open the image in gray-level
	image = cv::imread(path_boldt, 0);

	time = static_cast<double>(cv::getTickCount());
	sharpenIterator(image, result);
	time = (static_cast<double>(cv::getTickCount()) - time) / cv::getTickFrequency();
	std::cout << "time 3= " << time << std::endl;

	cv::namedWindow("Sharpened Image");
	cv::imshow("Sharpened Image", result);

	// test sharpen2D

	image = cv::imread(path_boldt);
	time = static_cast<double>(cv::getTickCount());
	sharpen2D(image, result);
	time = (static_cast<double>(cv::getTickCount()) - time) / cv::getTickFrequency();
	std::cout << "time 2D= " << time << std::endl;
	cv::namedWindow("Image 2D");
	cv::imshow("Image 2D", result);
	cv::waitKey();
	return 0;
}

int main()
{
	test();
	system("pause");
	return 0;
}

3、remapping.cpp

结果

在这里插入图片描述

测试代码


#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

#include <math.h>

// remapping an image by creating wave effects
static void wave(const cv::Mat &image, cv::Mat &result) {

	// the map functions
	cv::Mat srcX(image.rows,image.cols,CV_32F); // x-map
	cv::Mat srcY(image.rows,image.cols,CV_32F); // y-map

	// creating the mapping
	for (int i=0; i<image.rows; i++) {
		for (int j=0; j<image.cols; j++) {

			srcX.at<float>(i,j)= j;
			srcY.at<float>(i,j)= i+3*sin(j/6.0);

			// horizontal flipping
			// srcX.at<float>(i,j)= image.cols-j-1;
			// srcY.at<float>(i,j)= i;
		}
	}

	// applying the mapping
	cv::remap(image,  // source image
		      result, // destination image
			  srcX,   // x map
			  srcY,   // y map
			  cv::INTER_LINEAR); // interpolation method
}

static int test()
{
	// open image
	std::string path_boldt = "F:/images/boldt.jpg";
	cv::Mat image= cv::imread(path_boldt,0);

	cv::namedWindow("Image");
	cv::imshow("Image",image);

	// remap image
	cv::Mat result;
	wave(image,result);

	cv::namedWindow("Remapped image");
	cv::imshow("Remapped image",result);

	cv::waitKey();
	return 0;
}

int main()
{
	test();
	system("pause");
	return 0;
}

4、saltImage.cpp

结果

在这里插入图片描述

测试代码

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <random>

// Add salt noise to an image
static void salt(cv::Mat image, int n) {

	// C++11 random number generator
	std::default_random_engine generator;
	std::uniform_int_distribution<int> randomRow(0, image.rows - 1);
	std::uniform_int_distribution<int> randomCol(0, image.cols - 1);

	int i,j;
	for (int k=0; k<n; k++) {

		// random image coordinate
		i= randomCol(generator);
		j= randomRow(generator);
 
		if (image.type() == CV_8UC1) { // gray-level image

			// single-channel 8-bit image
			image.at<uchar>(j,i)= 255; 

		} else if (image.type() == CV_8UC3) { // color image

			// 3-channel image
			image.at<cv::Vec3b>(j,i)[0]= 255; 
			image.at<cv::Vec3b>(j,i)[1]= 255; 
			image.at<cv::Vec3b>(j,i)[2]= 255; 

			// or simply:
			// image.at<cv::Vec3b>(j, i) = cv::Vec3b(255, 255, 255);
		}
	}
}

// This is an extra version of the function
// to illustrate the use of cv::Mat_
// works only for a 1-channel image
static void salt2(cv::Mat image, int n) {

	// must be a gray-level image
	CV_Assert(image.type() == CV_8UC1);
	// C++11 random number generator
	std::default_random_engine generator;
	std::uniform_int_distribution<int> randomRow(0, image.rows - 1);
	std::uniform_int_distribution<int> randomCol(0, image.cols - 1);
	// use image with a Mat_ template
	cv::Mat_<uchar> img(image);
    //  or with references:
    //	cv::Mat_<uchar>& im2= reinterpret_cast<cv::Mat_<uchar>&>(image);
	int i,j;
	for (int k=0; k<n; k++) {
		// random image coordinate
		i = randomCol(generator);
		j = randomRow(generator);

		// add salt
		img(j,i)= 255; 
	}
}


static int test()
{
	// open the image
	std::string path_boldt = "F:/images/boldt.jpg";
	cv::Mat image= cv::imread(path_boldt,1);
	// call function to add noise
	salt(image,3000);
	// display result
	cv::namedWindow("Image");
	cv::imshow("Image",image);
	// write on disk
	cv::imwrite("salted.bmp",image);
	cv::waitKey();
	// test second version
	image= cv::imread(path_boldt,0);
	salt2(image, 500);
	cv::namedWindow("Image");
	cv::imshow("Image",image);
	cv::waitKey();
	return 0;
}

int main()
{
	test();
	system("pause");
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值