[Opencv] Opencv pixel processing and access

Opencv pixel processing and access

For image processing, if we understand the specific image processing algorithms, then we will be able to implement these algorithms through direct manipulation of pixels picture. Therefore, this article will summarize some knowledge Opencv pixel processing and access.

1. color space reduction

1.1 Color Space necessity reduced

Nature of the image is a matrix, a pixel is composed of one. Save picture data tend to take up a huge space. If the single-channel black and white pictures, each pixel with 0-255 numbers to represent the 256 colors. And if it is a three-channel color images, each pixel will have 256x256x256 possible colors, which undoubtedly is a huge data storage for pens overhead.

If the color space reduction, can effectively reduce data storage pressure. Our method can be approximated by the color, reduce the color space. For example, for a channel 256 colors: 0-10 represented as 0 , 11-20 expressed as 1 ... and so on, then we only need 26 digits to represent the color of a channel, for the three-channel color map, this storage compression ratio to a more objective, 256x256x256 reduced to 26x26x26 .

How to achieve this color approximated it? In the c ++, int type having a cut-off of decimal places of the division function, may this way, color space processing, the following formula

I n e w = I The l d 10 10 New = \ frac {Old} {10} * 10
Example:
Iold = 23 is, then Inew = 23/10 * 10 =

1.2 look-up table method to reduce color space

But if all the pixels have to do a similar calculation, but also a huge amount of calculation. So, we can simplify the process of using the look-up table idea. We can create a record of 0-256 after which correspond to digital conversion tables, so you do not need to calculate every time, but you can find the conversion table.

	//查找表的创建
    uchar table[256];
	int divideWidth = 100;
	for (int i = 0; i < 256; i++)
	{
		table[i] = i / divideWidth*divideWidth;
	}

Then the picture is assumed that each pixel is p [i], the following transformation can be achieved by reducing the color space

p[i]=table[p[i]];

1.3 LUT function

Opencv built into a lookup table function LUT, used for color space compression. Its function is defined as:

 void LUT(InputArray src, InputArray lut, OutputArray dst);

The first argument: input image
second argument: a lookup table
third parameter: the output picture
type These three parameters are the type of Mat

Examples of use

#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
using namespace std;
int main()
{
   //创建数值表
   uchar table[256];
   int dividedValue = 100;
   for (int i = 0; i < 256; i++)
   {
   	table[i] = i / dividedValue * dividedValue;
   }

   //定义图片
   Mat srcImg, lut, dstImg;
   srcImg = imread("1.png");

   //创建查找表
   lut.create(1, 256, CV_8UC1); //查找表一个通道就可以,处理三通道图片的时候,会把三个通道都安装lut的规则进行变换
   uchar* p = lut.data;
   for (int i = 0; i < 256; i++)
   {
   	p[i] = table[i];
   }
   
   //查找表函数
   imshow("a", srcImg);
   LUT(srcImg, lut, dstImg);
   imshow("b", dstImg);
   
   waitKey(0);
}

Here Insert Picture Description

2. The operating efficiency determination program

The image processing must understand the operational efficiency of image processing algorithms, this can be determined by running time of the program, there are two such functions:

double getTickFrequency();//指示1秒钟CPU能够运行多少个周期
int64 getTickCount(); //用来判断cpu当前的运行周期

By these two functions we can determine the running time of a program, for example as follows:

double t1=(double)getTickCount();
//do something
 t1 = ((double)getTickCount()-t1)/getTickFrequency();
 cout << t1 << endl;

3. The method of accessing pixels in an image

3.1 Pointer

Features pointer by accessing pixel is: the fastest, but the pointer itself has properties unsafe.
Worded as follows:

#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
using namespace std;

void colorReduce(Mat& srcImg, Mat& dstImg, int dividedValue)
{
	//创建查找表
	char table[256];
	for (int i = 0; i < 256; i++)
	{
		table[i] = i / dividedValue * dividedValue;
	}
	//记录图片数据
	int row = srcImg.rows;
	int col = srcImg.cols;
	int channel = srcImg.channels();
	srcImg.copyTo(dstImg);

	//使用指针的方法访问像素
	for (int i = 0; i < row; i++)
	{
		uchar* p = dstImg.ptr<uchar>(i);  //ptr是mat类的一个模板函数,返回值是第i行的头指针,尖括号里放的是返回值类型
		for (int j = 0; j < col * channel; j++)
		{
			p[j] = table[p[j]];
		}
	}

}
int main()
{
	Mat srcImg, dstImg;
	srcImg = imread("1.png");
	srcImg.copyTo(dstImg);
	imshow("a", dstImg);
	colorReduce(srcImg, dstImg, 100);
	imshow("b", dstImg);
	waitKey(0);
}

3.2 iterator

It features iterator access pixel is: only need to know the address of the first picture of a pixel and the last pixel address can traverse the pixels. Operation is very simple, and there is no offside memory problems, so it's safe.

#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
using namespace std;

void colorReduce(Mat& srcImg, Mat& dstImg, int dividedValue)
{
	//创建查找表
	char table[256];
	for (int i = 0; i < 256; i++)
	{
		table[i] = i / dividedValue * dividedValue;
	}
	//记录图片数据
	int row = srcImg.rows;
	int col = srcImg.cols;
	int channel = srcImg.channels();
	srcImg.copyTo(dstImg);

	switch (channel)
	{
		//处理单通道的灰色图
	case 1:
	{
		MatIterator_<uchar> it, end;//创建迭代器
	for (it = dstImg.begin<uchar>(), end = dstImg.end<uchar>(); it != end; it++)
	{
		(*it) = table[(*it)];
	}
	break;
	}
	//处理三通道的彩色图
	case 3:
	{
		cv::Mat_<cv::Vec3b>::iterator it = dstImg.begin<Vec3b>();//创建迭代器
		cv::Mat_<cv::Vec3b>::iterator end = dstImg.end<Vec3b>();
		for (; it != end; it++)
		{
			(*it)[0] = table[(*it)[0]];
			(*it)[1] = table[(*it)[1]];
			(*it)[2] = table[(*it)[2]];

		}
		break;
	}

	}

}
int main()
{
	Mat srcImg, dstImg;
	srcImg = imread("1.png");
	srcImg.copyTo(dstImg);
	imshow("a", dstImg);
	colorReduce(srcImg, dstImg, 100);
	imshow("b", dstImg);
	waitKey(0);
}

Here we must pay attention to a problem that when a case statement which defined variables, be sure to add {}, otherwise it will error

3.3 Dynamic Address

Dynamic memory usage at Mat class is characterized by: intuitive, it can very easily be seen that the value of the ranks
worded as follows:

#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
using namespace std;

void colorReduce(Mat& srcImg, Mat& dstImg, int dividedValue)
{
	//创建查找表
	char table[256];
	for (int i = 0; i < 256; i++)
	{
		table[i] = i / dividedValue * dividedValue;
	}
	//记录图片数据
	int row = srcImg.rows;
	int col = srcImg.cols;
	int channel = srcImg.channels();
	srcImg.copyTo(dstImg);

	switch (channel)
	{
		//处理单通道的灰色图
	case 1:
	{
		for (int i = 0; i < row; i++)
		{
			for (int j = 0; j < col; j++)
			{
				dstImg.at<uchar>(i, j) = table[dstImg.at<uchar>(i, j)];
			}
		}
		break;
	}
	//处理三通道的彩色图
	case 3:
	{
		for (int i = 0; i < row; i++)
		{
			for (int j = 0; j < col; j++)
			{
				dstImg.at<Vec3b>(i, j)[0] = table[dstImg.at<Vec3b>(i, j)[0]]; 
				dstImg.at<Vec3b>(i, j)[1] = table[dstImg.at<Vec3b>(i, j)[1]];
				dstImg.at<Vec3b>(i, j)[2] = table[dstImg.at<Vec3b>(i, j)[2]];
			}
		}

		break;
	}

	}

}
int main()
{
	Mat srcImg, dstImg;

	srcImg = imread("1.png");
	srcImg.copyTo(dstImg);
	imshow("a", dstImg);
	colorReduce(srcImg, dstImg, 100);
	imshow("b", dstImg);
	waitKey(0);
}

references

[. 1] OpenCV two study notes (Scan Images) https://blog.csdn.net/jameshater/article/details/50756729
[2] talk OpenCV the lookup table in the lookup table LUT function https: //blog.csdn. net / jameshater / article / details / 50759650? utm_source = blogxgwz8

Published 14 original articles · won praise 1 · views 501

Guess you like

Origin blog.csdn.net/qq_41741344/article/details/104355066