1. 程式人生 > >【影象處理】影象畫素隨機化:雪花漫天飛

【影象處理】影象畫素隨機化:雪花漫天飛

近來經常和心理系做實驗,總是有各種“什麼什麼隨機化,刺激的物理性質保持一樣。。”的需求。之前做《去掩蔽》的實驗時,有一套圖片就是做的畫素隨機化,這是最簡單的隨機化了。當時影象只有兩種畫素,灰的和深灰的,而且深灰的比較少。


於是我就統計了深灰畫素點的個數,然後在一張同樣大的灰色圖片中的隨機位置灑深灰畫素點。

int pix_count=0;
	for(int i=0;i<img_width+eye_shift;i++){
		uchar* p=sub_masker.ptr<uchar>(i);
		for(int j=0;j<img_width+eye_shift;j++){
			if(p[j*3]==78){
				pix_count++;
			}
		}
	}
	//cout<<pix_count<<endl;
	int pix_width=img_width+eye_shift;
	while(pix_count>0){
		int rand_x=rand()%pix_width;
		int rand_y=rand()%pix_width;
		uchar* p_pix=pix_masker.ptr<uchar>(rand_x);
		if(p_pix[rand_y*3]==128){
			p_pix[rand_y*3]=78;
			p_pix[rand_y*3+1]=78;
			p_pix[rand_y*3+2]=78;
			pix_count--;
			//	cout<<pix_count<<endl;
		}
	}

大致效果如上圖(*忽略幾個字母,是疊加了目標刺激的效果)。但這次需要對一個刺激視訊中每一幀做隨機化,且視訊是彩色的。
我一開始的思路是對畫素中每一個點,隨機找另外一個點交換他們的RGB值。
		Mat frame_copy(frame_rows,fram_cols, CV_8UC3,Scalar(0,0,0));
		frame.copyTo(frame_copy);
		Mat frame_tag=Mat::zeros(frame_rows,fram_cols, CV_8UC1);
		for(int i=0;i<frame_rows;i++){
			uchar* p=frame_copy.ptr<uchar>(i);
			for(int j=0;j<fram_cols;j+=3){
				uchar r=p[0];
				uchar b=p[1];
				uchar g=p[2];
				int rand_row=rand()%frame_rows;
				int rand_col=rand()%fram_cols;
			//	cout<<rand_row<<" "<<rand_col<<endl;
				uchar* rand_p=frame_copy.ptr<uchar>(rand_row);
				p[0]=rand_p[rand_col*3+0];
				p[1]=rand_p[rand_col*3+1];
				p[2]=rand_p[rand_col*3+2];
				rand_p[rand_col*3+0]=r;
				rand_p[rand_col*3+1]=b;
				rand_p[rand_col*3+2]=g;
			}
		}
但不知為何,實現出來的效果是這樣的。。。莫不是因為每個點都被隨機了,在後面的時候又以一定的概率被隨機回去了???於是還是改成了原來撒點的思路,對應新建一幅一樣大的黑色圖,逐點讀取原圖的畫素點,如果遇到非黑色的點,就在新圖隨機找一個黑色的(也就是未被修改過的點)修改畫素值為原圖中此點的畫素值。完整程式碼:
int main(){
	VideoCapture inputVideo("情緒學習.wmv");
	if ( !inputVideo.isOpened()){
		cout << "Could not open the input video."  << endl;
		return -1;
	}
	Size S = Size((int) inputVideo.get(CV_CAP_PROP_FRAME_WIDTH), //Acquire input size
		(int) inputVideo.get(CV_CAP_PROP_FRAME_HEIGHT));
	int ex = static_cast<int>(inputVideo.get(CV_CAP_PROP_FOURCC)); // Get Codec Type- Int form
	VideoWriter outputVideo; // Open the output
	outputVideo.open("ZhongXing.wmv",CV_FOURCC('M','J','P','G'), 30,S, true);
	srand((unsigned)time(NULL));
	int frame_count=0;
	while(true){
		Mat frame;
		inputVideo>>frame;
		if(frame.empty())
			break;
		int frame_rows=frame.rows;
		int fram_cols=frame.cols;
		Mat frame_copy(frame_rows,fram_cols, CV_8UC3,Scalar(0,0,0));
		Mat frame_tag=Mat::zeros(frame_rows,fram_cols, CV_8UC1);
		for(int i=0;i<frame_rows;i++){
			uchar* p_frame=frame.ptr<uchar>(i);
			for(int j=0;j<fram_cols;j+=3){
				uchar r=p_frame[j+0];
				uchar b=p_frame[j+1];
				uchar g=p_frame[j+2];
				if((r>0)||(b>0)||(g>0)){
					bool if_tag=false;
					while(!if_tag){
						int rand_row=rand()%frame_rows;
						int rand_col=rand()%fram_cols;
						uchar* p_tag=frame_tag.ptr<uchar>(rand_row);
						uchar* p_copy=frame_copy.ptr<uchar>(rand_row);
						if(p_tag[rand_col]==1)
							continue;
						else{
							p_tag[rand_col]=1;
							p_copy[rand_col*3+0]=r;
							p_copy[rand_col*3+1]=b;
							p_copy[rand_col*3+2]=g;
							if_tag=true;
						}
					}
				}
			}
		}
		cout<<"Write frame: "<<frame_count++<<endl;
		outputVideo<<frame_copy;
	}
	cout<<"Finished Writing"<<endl;
	return 0;
}

然後就實現了漫天飛舞的隨機雪花效果啦~