OpenCV region coding and threshold coding to achieve image compression (8*8DCT transform, retain 50% coefficient) _ Image processing

Source: Internet
Author: User
Tags abs cos pow

"Digital Image Processing" of an experimental operation is required as follows:


I found on the Internet on the topic of the MATLAB version of the code, links are as follows:

Http://wenku.baidu.com/link?url=6WlcVIE8sAg2Lnj6R7PQlv7tL7sNvBb7uhN3YZ37hj7xb855G_ Ea7yu0ek34yl7uvknrrltuubaooneos5sb-wcmywsfggaozhk-ilau6rk

I refer to the above link, mainly made the following two aspects of the changes:

(1) The reference code with OPENCV again (the main difficulty is that OpenCV seems to have no similar to Matlab blkproc so convenient block processing function, I adopted the approach is to define a 8*8 area of interest in the picture

Slide above) (My code runs on the vs2013+opencv3.1);

(2) The reference Code, the threshold coding part of a bit inexplicable, I used the method is: after the DCT transformation of each 8*8 coefficient block to take the median (after the absolute value), the absolute value is less than the median coefficient of zero, each 8*8

Blocks have different median values, and there are different thresholds. The key code for the reference code in the Threshold coding section is as follows:




The above program uses 8*8 matrix G less than the coefficient of the median to 0 as the mask, do not understand why the G matrix, even if so, C=median (b) This procedure also has problems, for example:

B=[-3-2-1 0 1 2 3], then median (b) is 0, which obviously does not achieve the effect of removing the coefficients less than the median value, so the C=median (b) should be converted to C=median (ABS (b)).

The main ideas of my program are as follows:

(1) reading the original picture in grayscale, and converting the picture into double type;

(2) The DCT transform of the original image is 8*8 by using the BLKPROC_DCT function which is written by itself;

(3) by using the regionalcoding and thresholdcoding functions, the region coding and threshold coding of the coefficients matrix after DCT transform are respectively carried out.

(4) using the IDCT function, the original picture is recovered from the results obtained from the regionalcoding and thresholdcoding functions, showing and comparing the results.

The following is the specific code (the runtime only needs to modify the image path after Imread):

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

using namespace CV;	void Blkproc_dct (Mat);	function equivalent to the BLKPROC function of Matlab (Blkproc (i,[8 8], ' p1*x*p2 ', G,g ')), for the image to do 8*8 block DCT Mat BLKPROC_IDCT (Mat);	function equivalent to the BLKPROC function of Matlab (Blkproc (i,[8 8], ' p1*x*p2 ', G ', g)), used to do 8*8 block DCT inverse transform, restore the original image void Regionalcoding (Mat);	The domain coding function is equivalent to the Blkproc function of Matlab (Blkproc (i1,[8 8), ' p1.*x ', a) ' void thresholdcoding (Mat);	Threshold encoding function, function equivalent to the BLKPROC function of Matlab (Blkproc (i1,[8 8), ' p1.*x ', a) double Get_mediannum (Mat &); Gets the median value of the matrix for the threshold encoding #define M_PI 3.141592653 int main () {Mat ucharimg = Imread ("f:\\my_desktop\\data\\frame\\hand_test\\h	And_test_0.jpg ", 0);
	Read the original image imshow ("srcimg", ucharimg) in the form of grayscale graphs;
	Mat doubleimg;	Ucharimg.convertto (doubleimg, cv_64f);	The original image is converted into a double type image, which facilitates the subsequent 8*8 block DCT transform BLKPROC_DCT (doubleimg);
	The original image is done 8*8 block DCT Transform//respectively region coding and threshold coding Mat doubleimgregion, Doubleimgthreshold;
	Doubleimgregion = Doubleimg.clone ();
	Doubleimgthreshold = Doubleimg.clone (); Regionalcoding (DoublEimgregion);	The coefficients of DCT transform are encoded thresholdcoding (doubleimgthreshold);
	The coefficients of DCT transform are encoded by the threshold encoding//inverse DCT transform Mat ucharimgregion, ucharimgthreshold;	
	Ucharimgregion = BLKPROC_IDCT (doubleimgregion);
	Imshow ("regionalcoding", ucharimgregion);
	Ucharimgthreshold = BLKPROC_IDCT (doubleimgthreshold);
	Imshow ("thresholdcoding", ucharimgthreshold);
Waitkey (0);
	} void Blkproc_dct (Mat doubleimgtmp) {Mat ucharimgtmp;	Mat Dctmat = Mat (8, 8, CV_64FC1);	The Matrix Mat Dctmatt for the 8*8 of DCT transform;	Dctmat Matrix transpose Mat Roimat = Mat (8, 8, CV_64FC1);	When used for chunking, move the Double A = 0, q in the original image. 
				Coefficients for DCT transform (int i = 0; i < dctmat.rows i++) {for (int j = 0; J < Dctmat.cols; j) {if (i = = 0) {
			A = POW (1.0/dctmat.rows, 0.5);
			else {a = POW (2.0/dctmat.rows, 0.5);
			} q = ((2 * j + 1) *i*m_pi)/(2 * dctmat.rows);
		Dctmat.at<double> (i, j) = A*cos (q);
	} Dctmatt = dctmat.t (); Roimat in doubleimgtmp with 8 for the step move to achieve with the MATLAB block processing function Blkproc the same effect//This program, if the picture of high or wide is not 8 integer times, the last less than 8 of the part does notfor processing int rnum = DOUBLEIMGTMP.ROWS/8;
	int cnum = DOUBLEIMGTMP.COLS/8; for (int i = 0; i < Rnum. i++) {for (int j = 0; J < Cnum; J +) {Roimat = Doubleimgtmp (Rect (J * 8, I * 8, 8
			, 8));
		Roimat = Dctmat*roimat*dctmatt;
	} doubleimgtmp.convertto (Ucharimgtmp, cv_8u);
Imshow ("Dctimg", ucharimgtmp); Mat BLKPROC_IDCT (Mat doubleimgtmp) {//BLKPROC_DCT almost the same, the only difference is: Roimat = dctmatt*roimat*
	Dctmat (Transpose matrix Dctmatt and Dctmat switched position) Mat ucharimgtmp;	
	Mat Dctmat = Mat (8, 8, CV_64FC1);	
	Mat Dctmatt;	
	Mat Roimat = Mat (8, 8, CV_64FC1);	
	Double A = 0, q; for (int i = 0; i < dctmat.rows. i++) {for (int j = 0; J < Dctmat.cols; j) {if (i = = 0) {a = Pow
			(1.0/dctmat.rows, 0.5);
			else {a = POW (2.0/dctmat.rows, 0.5);
			} q = ((2 * j + 1) *i*m_pi)/(2 * dctmat.rows);
		Dctmat.at<double> (i, j) = A*cos (q);
	} Dctmatt = dctmat.t ();
	int rnum = DOUBLEIMGTMP.ROWS/8;
	int cnum = DOUBLEIMGTMP.COLS/8; for (int i = 0; I < rNum;
			i++) {for (int j = 0; J < Cnum; J +) {Roimat = Doubleimgtmp (Rect (J * 8, I * 8, 8, 8));
		Roimat = Dctmatt*roimat*dctmat;
	} doubleimgtmp.convertto (Ucharimgtmp, cv_8u);
return ucharimgtmp;
	} void Regionalcoding (Mat doubleimgtmp) {int rnum = DOUBLEIMGTMP.ROWS/8;
	int cnum = DOUBLEIMGTMP.COLS/8;
	Mat ucharimgtmp;	Mat Roimat = Mat (8, 8, CV_64FC1); For block processing, move for (int i = 0; i < rnum; i++) {for (int j = 0; J < Cnum; J +) {Roimat = Doubleimgtmp
			(Rect (J * 8, I * 8, 8, 8)); for (int r = 0; r < roimat.rows. r++) {for (int c = 0; c < roimat.cols C + +) {//8*8 block, after four rows 0 I
					F (r>4) {roimat.at<double> (r, c) = 0.0;
	}}} Doubleimgtmp.convertto (Ucharimgtmp, cv_8u);
Imshow ("Regionalcodingimg", ucharimgtmp);
	} void Thresholdcoding (Mat doubleimgtmp) {int rnum = DOUBLEIMGTMP.ROWS/8;
	int cnum = DOUBLEIMGTMP.COLS/8;
	Double mediannumtmp = 0;
	Mat ucharimgtmp; Mat Roimat =Mat (8, 8, CV_64FC1); For block processing, move for (int i = 0; i < rnum; i++) {for (int j = 0; J < Cnum; J +) {Roimat = Doubleimgtmp
			(Rect (J * 8, I * 8, 8, 8));
			Mediannumtmp = Get_mediannum (Roimat); for (int r = 0; r < roimat.rows. r++) {for (int c = 0; c < roimat.cols C + +) {if (ABS (ROIMAT.AT&LT
					;d ouble> (r,c)) <0) {roimat.at<double> (r, c) = 0;
	}}} Doubleimgtmp.convertto (Ucharimgtmp, cv_8u);
Imshow ("Thresholdcodingimg", ucharimgtmp);
	Double Get_mediannum (Mat & Imageroi)//Get the median value of the matrix {vector<double> vectortemp;
	Double tmppixelvalue = 0; for (int i = 0; i < imageroi.rows i++)//pull the area of interest matrix into a vector {for (int j = 0; J < Imageroi.cols; J +) {Vectort
		Emp.push_back (ABS (Imageroi.at<double> (i, j));
		for (int i = 0; i < vectortemp.size ()/2; i++)//Sort {for (int j = i + 1; j < Vectortemp.size (); {if (vectortemp.at (i) > vectortemp.at (j)) {DoUble temp;
				temp = vectortemp.at (i);
				vectortemp.at (i) = vectortemp.at (j);
			vectortemp.at (j) = temp;	}} return vectortemp.at (Vectortemp.size ()/2-1); Returns the median}



Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.