at()函式改變影象的對比度和亮度(openCV)(4)

一個蘿蔔壹個坑發表於2018-01-03

at()函式

函式at()來實現讀去矩陣中的某個畫素,或者對某個畫素進行賦值操作。下面兩行程式碼演示了at()函式的使用方法。

uchar value = grayim.at(i,j);//讀出第i行第j列畫素值

grayim.at(i,j)=128; //將第i行第j列畫素值設定為128

如果要對影象進行遍歷,可以參考下面的例程。這個例程建立了兩個影象,

分別是單通道的grayim以及3個通道的colorim,然後對兩個影象的所有畫素值

進行賦值,最後現實結果。

for( int i = 0; i < colorim.rows; ++i)

for( int j = 0; j < colorim.cols; ++j )

{

Vec3b pixel;

pixel[0] = i%255; //Blue

pixel[1] = j%255; //Green

pixel[2] = 0; //Red

colorim.at(i,j) = pixel;

}

}

改變影象亮度和透明度的基本實現方法:

實現效果的核心程式碼

for( int i = 0; i < imageDpi.rows; i++) {        

         for( int j = 0; j < imageDpi.cols; j++) {           

                 for( int k = 0; k < 3; k++) {                

                       new_image.at(i, j)[k] = saturate_cast(alpha * ( imageDpi.at(i, j)[k]) + betal);

         }       

     }

}

為了訪問影象的每一個畫素,使用語法: image.at(i, j)[k] ,其中, i 是畫素所在的行, j 是畫素所在的列, k 是R、G、B(0、1、2)之一。

用 saturate_cast 對結果進行轉換,以確保它為有效值。

實現效果

at()函式改變影象的對比度和亮度(openCV)(4)

實現程式碼

// 需要的公共屬性

using namespace cv;

Mat imageDpi;

Mat new_image;

@interface ViewController ()

{

UIImageView *imagView2;

float alpha;

float betal;

}

初始化介面和Mat物件等

UIImageView *imagView1 = [[UIImageView alloc] initWithFrame:CGRectMake(0, 100, self.view.bounds.size.width, 200)];

[self.view addSubview:imagView1];

imagView2 = [[UIImageView alloc] initWithFrame:CGRectMake(0, 350, self.view.bounds.size.width, 200)];

[self.view addSubview:imagView2];

UIImage *image = [UIImage imageNamed:@"try.png"];

imagView1.image = image;

// 將圖片轉換為Mat物件

UIImage *image3 = [UIImage imageNamed:@"try.png"];

//    Mat imageDpi;

UIImageToMat(image3, imageDpi);

// 初始化接收後最後修改結果的物件

new_image = Mat::zeros(imageDpi.size(), imageDpi.type());

imagView2.image = image;

UISlider *slider1 = [[UISlider alloc] initWithFrame:CGRectMake(0,600, self.view.bounds.size.width, 20)];

slider1.value = 0;

slider1.tag = 1000;

slider1.maximumValue = 3;

[slider1 addTarget:self action:@selector(sliderValueChanged:) forControlEvents:UIControlEventValueChanged];// 針對值變化新增響應方法

[self.view addSubview:slider1];

UISlider *slider2 = [[UISlider alloc] initWithFrame:CGRectMake(0,630, self.view.bounds.size.width, 20)];

slider2.value = 0;

slider2.tag = 2000;

slider2.maximumValue = 100;

[slider2 addTarget:self action:@selector(sliderValueChanged:) forControlEvents:UIControlEventValueChanged];// 針對值變化新增響應方法

[self.view addSubview:slider2];

實現方法

- (void)sliderValueChanged:(UISlider *)sender{   

 NSLog(@"%f",sender.value);   

 if (sender.tag == 1000) {      

            alpha = sender.value;   

    }else{       

     betal = sender.value;;   

     }   

 for( int i = 0; i < imageDpi.rows; i++) {       

for( int j = 0; j < imageDpi.cols; j++) {           

for( int k = 0; k < 3; k++) {               

 new_image.at(i, j)[k] = saturate_cast(alpha * ( imageDpi.at(i, j)[k]) + betal);

}

}

}


// 最後需要將 Mat 轉換為 UIImage 物件

UIImage *image = MatToUIImage(new_image);

imagView2.image = image;

}

如果要遍歷影象,並不推薦使用at()函式。使用這個函式的優點是程式碼的可讀性高,但是效率並不是很高,可以使用迭代器。

相關文章