初期プローブopencv-ピクセルを操作する(ピクセル値の反転、ピクチャの混合)
ピクセルの操作
ピクセルを操作するには、まずピクセルポイントを抽出することを自然に考えています.前の文章では、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タイプ)
ここでのブレンド方法は線形ブレンド演算(重み付き)である.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つのピクチャのピクセル値です.コードは次のとおりです.
ピクセルを操作するには、まずピクセルポイントを抽出することを自然に考えています.前の文章では、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;
}