初期プローブopencv-ピクセルを操作する(ピクセル値の反転、ピクチャの混合)

19160 ワード

ピクセルの操作
ピクセルを操作するには、まずピクセルポイントを抽出することを自然に考えています.前の文章では、Matオブジェクトのptr()関数を利用して、ポインタタイプのピクセルポイントを返すことができますが、ポインタを操作するのはいつも私たちの慣行と合わないようで、危険を感じています.だからこの文章は主にat()関数を使います
at():at(i,j)は、あるMatオブジェクトを読み出すi行j列の画素点を表し、戻り値は可変であり、ポインタ操作には関与しない.例は次のとおりです.
1.画像の画素値のコントラスト
この動作は、ピクチャが3次元、すなわちrgb色空間である場合、画素点データ型はucharではなく、Vec 3 bまたはVec 3 fであるべきであるピクチャの色空間に関連する.(Vec 3 b対応bgrのucharタイプ、Vec 3 f対応bgrのfloatタイプ)
#include 
#include 

using namespace cv;
using namespace std;

int main(int argc, char** argv) {
	Mat src = imread("E:/images/timg.jpg");
	if (src.empty()) {
		cout << "could not be found" << endl;
		return -1;
	}
	namedWindow("output", CV_WINDOW_AUTOSIZE);
	imshow("output", src);
	
	Mat dst;
	dst.create(src.size(), src.type()); //               
	int nc = src.channels();
	cout << nc << endl;
	
	//  src             
	for (int row = 0; row < height; row++) {
		for (int col = 0; col < width; col++) {
			if (nc == 1) {
				//            
				int gray = src.at<uchar>(row, col); //     
				dst.at<uchar>(row, col) = 255 - gray;
			}
			else if (nc == 3) {
			// Vec3b   bgr uchar  
			// Vec3f   bgr float  

				int b = src.at<Vec3b>(row, col)[0]; 
				int g = src.at<Vec3b>(row, col)[1];
				int r = src.at<Vec3b>(row, col)[2];
				dst.at<Vec3b>(row, col)[0] = 255 - b;
				dst.at<Vec3b>(row, col)[1] = 255 - g;
				dst.at<Vec3b>(row, col)[2] = 255 - r;
				//dst.at(row, col)[2] = 255 - r;
			}
			
		}
	}
	imshow("output3", dst);
	Mat m1 = Mat::zeros(src.size(),src.type());
	//  CV_8UC1    CV_32F    uchar   float32
	src.convertTo(m1, CV_32F);
	imshow("output4", m1);
	waitKey(0);
	return 0;
}
上に書いた2つのforループは書かないことができます.ギャップは実質的にビット演算が逆であるため、1つのapiでできます.
	//  api  
	bitwise_not(src, dst);  //             
2.2枚の画像のミックス
ここでのブレンド方法は線形ブレンド演算(重み付き)である.F(x,y)=a l p h a∗f(x,y)+(1−a l p h a)∗g(x,y)F(x,y)=alpha*f(x,y)+(1−alpha)*g(x,y)F(x,y)=alpha∗f(x,y)+(1−alpha)∗g(x,y)alphaは0−1に属し、すなわち、代表2枚の図を混合したときのどの図が占める割合がより大きいか.f(x,y),g(x,y)はそれぞれsrc 1,src 2,すなわち混合演算の2つのオブジェクトを表し,F(x,y)は混合後に生成されたピクチャを表す.演算オブジェクトは、自然に2つのピクチャのピクセル値です.コードは次のとおりです.
#include 
#include 

using namespace cv;
using namespace std;
//      
int main(int argc, char** argv) {
	Mat src1 = imread("E:/images/0.jpg");
	Mat src2 = imread("E:/images/1.jpg");
	if (src1.empty() || src2.empty()) {
		cout << "could not be found " << endl;
		return -1;
	}
	namedWindow("output01", CV_WINDOW_NORMAL);
	imshow("output01", src1);
	namedWindow("output02", CV_WINDOW_NORMAL);
	imshow("output02", src2);
	Mat dst = Mat::zeros(src1.size(), src1.type());
	double alpha = 0.5; //     
	if (src1.cols == src2.cols && src1.rows == src2.rows && src1.type() == src2.type()) {
		addWeighted(src1, alpha, src2, 1 - alpha, 0.0, dst) ;//            
		// multiply(src1, src2, dst, 1.0); //     
		namedWindow("output03", CV_WINDOW_AUTOSIZE);
		imshow("output03", dst);
	}

	waitKey(0);

	return 0;
}