新手學習就是苦啊,好多東西都要一點點的摸索,之前的經驗太少,積累太少,許多問題太簡單了,問別人都不好開口,誰讓自己太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()將字符轉換爲浮點型……