opencv學習之感興趣區域(ROI)

新手學習就是苦啊,好多東西都要一點點的摸索,之前的經驗太少,積累太少,許多問題太簡單了,問別人都不好開口,誰讓自己太low了啊!

那就自己折騰唄……

今天看了opencv的矩陣和圖像操作部分內容,這裏把這折騰的過程弄上來了

書上給了兩種獲得感興趣矩形區域的方式


一個是直接用函數  cvSetImageROI(IplImage* image, Cvrect  rect),    其中image是加載的一幅圖像,  rect =  cvRect(x, y, width,  height) ,x,y給出了矩形在原圖像中的起點(從左上起),width,height給出了矩形的寬和高。    書中示例給出了將該矩形區域的藍色通道增加150  ( 即語句cvAddS(interestimg, cvScalar(add), interestimg))後的圖像輸出。書中源碼如下:


#include <cv.h>
#include <highgui.h>
// ch3_ex3_12 image_name x y width height add# 
int main(int argc, char** argv)
{

    IplImage* src;
    cvNamedWindow("Example3_12_pre", CV_WINDOW_AUTOSIZE);
    cvNamedWindow("Example3_12_post", CV_WINDOW_AUTOSIZE);  
    if( argc == 7 && ((src=cvLoadImage(argv[1],1)) != 0 ))
    {
		int x = atoi(argv[2]);
		int y = atoi(argv[3]);
		int width = atoi(argv[4]);
		int height = atoi(argv[5]);
		int add = atoi(argv[6]);
		cvShowImage( "Example3_12_pre", src);
		cvSetImageROI(src, cvRect(x,y,width,height));
		cvAddS(src, cvScalar(add),src);
		cvResetImageROI(src);
		cvShowImage( "Example3_12_post",src);
      cvWaitKey();
    }
  cvReleaseImage( &src );
  cvDestroyWindow("Example3_12_pre");
  cvDestroyWindow("Example3_12_post");   
    return 0;
}


另一個方法是通過使用widthStep來直接達到與上面相同的效果,這個相當於通過原圖的信息來建立一個需要的長寬的矩形IplImage類型,然後再根據期望的感興趣區域位置,找到矩形的左上角在原圖上的座標,這樣就成功劃出了感興趣矩形區域了

與此同時,根據後面的alpha融合的內容,試着將載入了另一幅圖像,然後選取了該圖像同樣大小的一部分,和原圖的感興趣區域按一定的權值融合了,於是使得操作區域出現了“你中有我,我中有你”的現象

 

#include <cv.h>
#include <highgui.h>
// ch3_ex3_12 image_name x y width height add# 
int main(int argc, char** argv)
{

	IplImage* src;
	IplImage* src2;
	cvNamedWindow("Example3_12_pre", CV_WINDOW_AUTOSIZE);
	cvNamedWindow("Example3_12_post", CV_WINDOW_AUTOSIZE);
	if (argc == 10 && ((src = cvLoadImage(argv[1], 1)) != 0))
	{
		src2 = cvLoadImage(argv[9]);
		IplImage* interestimg = cvCreateImageHeader(
			cvSize(250, 300),
			src->depth,
			src->nChannels
			);
		IplImage* interestimg2 = cvCreateImageHeader(
			cvSize(250, 300),
			src->depth,
			src->nChannels
			);
		interestimg2->origin = src2->origin;
		interestimg2->widthStep = src2->widthStep;
		interestimg2->imageData = src2->imageData + 12 * src2->widthStep + 12 * src2->nChannels;
		interestimg->origin = src->origin;
		interestimg->widthStep = src->widthStep;
		interestimg->imageData = src->imageData + 120 * src->widthStep + 120 * src->nChannels;
		int add = atoi(argv[6]);
		//double alpha = (double)atof(argv[7]);
		//double beta = (double)atof(argv[8]);
		cvShowImage("Example3_12_pre", src);
	    //cvAddS(interestimg, cvScalar(add), interestimg);
		cvAddWeighted(interestimg, alpha, interestimg2, beta, 0.0, interestimg);
		//interestimg->imageData = src->imageData + 120 * src->widthStep + 120 * src->nChannels + 1;
		//cvAddS(interestimg, cvScalar(20), interestimg);
		//interestimg->imageData = src->imageData + 120 * src->widthStep + 120 * src->nChannels + 2;
		//cvAddS(interestimg, cvScalar(30), interestimg);
		cvResetImageROI(src);
		cvShowImage("Example3_12_post", src);
		cvWaitKey();
	}
	cvReleaseImage(&src);
	cvDestroyWindow("Example3_12_pre");
	cvDestroyWindow("Example3_12_post");
	return 0;
}


書中源程序使用

         sub_img->imageData = interest_img->imageData +
          interest_rect.y * interest_img->widthStep  +
          interest_rect.x * interest_img->nChannels;

來找到感興趣區域的左上角座標,這樣是對藍色通道數據進行操作,我們可以在後面+1,或+2來對紅色或綠色通道來操作,如:interestimg->imageData = src->imageData + 120 * src->widthStep + 120 * src->nChannels + 1;來對紅色通道操作


在本程序中,出項了之前沒用過的函數“atoi()”,這是一個將字符轉換爲整形的函數,比如,命令參數中輸入的字符串“12”,可以用該函數轉換爲整形數“12”,同樣,atof()將字符轉換爲浮點型……






發佈了31 篇原創文章 · 獲贊 19 · 訪問量 16萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章