看完了數(shù)字圖像處理后,從頭開始使用opencv進(jìn)行相關(guān)內(nèi)容的實現(xiàn),使用的環(huán)境是VS2013+OpenCV2.4.9
1.圖像的加運算
加運算就是兩幅圖像對應(yīng)像素的灰度值或彩色分量進(jìn)行相加。主要有兩種用途,一種是消除圖像的隨機(jī)噪聲,主要做是講同一場景的圖像進(jìn)行相加后再取平均;另一種是用來做特效,把多幅圖像疊加在一起,再進(jìn)一步進(jìn)行處理。
對于灰度圖像,因為只有單通道,所以直接進(jìn)行相應(yīng)位置的像素加法即可,對于彩色圖像,則應(yīng)該將對應(yīng)的顏色的分量分別進(jìn)行相加。
通常來將,兩幅或多幅相加的圖像的大小和尺寸應(yīng)該相同。
以下為代碼部分,使用了兩種方法進(jìn)行實現(xiàn),一是使用迭代器進(jìn)行圖像的遍歷進(jìn)行相加,另一種是使用OpenCV中的addWeighted函數(shù)進(jìn)行線性相加。
//本程序?qū)崿F(xiàn)將兩張尺寸相同的圖像進(jìn)行相加//在對像素進(jìn)行操作時,使用的時迭代器的方法//2017-02-18#include <iostream>#include <opencv2/core/core.hpp>#include <opencv2/highgui/highgui.hpp>using namespace cv;using namespace std; int main(){ Mat img1, img2, result1; img1 = imread("1234.jpg"); img2 = imread("2345.jpg"); result1 = img1.clone(); Mat_<Vec3b>::iterator it = result1.begin<Vec3b>(); //result1初始位置的迭代器 Mat_<Vec3b>::iterator itend = result1.end<Vec3b>(); //result1終止位置的迭代器 Mat_<Vec3b>::iterator it1 = img1.begin<Vec3b>(); //img1初始迭代器 Mat_<Vec3b>::iterator it2 = img2.begin<Vec3b>(); //img2初始迭代器 //進(jìn)行遍歷 for (; it != itend; it++) { (*it)[0] = ((*it1)[0] + (*it2)[0]) /2; (*it)[1] = ((*it1)[1] + (*it2)[1]) /2; (*it)[2] = ((*it1)[2] + (*it2)[2]) /2; it1++; it2++; } namedWindow("原圖1",1); imshow("原圖1", img1); namedWindow("原圖2", 0); imshow("原圖2", img2); namedWindow("相加后的圖像",0); imshow("相加后的圖像", result1); Mat result2 = result1.clone(); addWeighted(img1, 1, img2, 1, 0,result2); namedWindow("addWeighted"); imshow("addWeighted", result2); waitKey(); return 0;}運行結(jié)果為:

2.圖像相減
減法運算就是兩幅圖像見對象像素的灰度值或彩色分量進(jìn)行相減,它可以用于目標(biāo)檢測,程序?qū)崿F(xiàn)還是使用兩種方法。
以下為程序部分
//本程序?qū)崿F(xiàn)兩個尺寸相同的圖像進(jìn)行相減的操作//分別使用遍歷像素的方法和addWeighted的方法#include <iostream>#include <opencv2/core/core.hpp>#include <opencv2/highgui/highgui.hpp>using namespace std;using namespace cv;uchar toZero(uchar a);//置零函數(shù),小于零則為0int main(){ Mat imag1, imag2, result1, result2; imag1 = imread("2345.jpg"); imag2 = imread("1234.jpg"); result1 = imag1.clone(); result2 = imag2.clone(); int rowNumber = result1.rows; int colNumber = result1.cols; for (int i = 0; i < rowNumber; i++) { for (int j = 0; j < colNumber; j++) { result1.at<Vec3b>(i, j)[0] = toZero(imag1.at<Vec3b>(i, j)[0] - imag2.at<Vec3b>(i, j)[0]); result1.at<Vec3b>(i, j)[1] = toZero(imag1.at<Vec3b>(i, j)[1] - imag2.at<Vec3b>(i, j)[1]); result1.at<Vec3b>(i, j)[2] = toZero(imag1.at<Vec3b>(i, j)[2] - imag2.at<Vec3b>(i, j)[2]); } } //addWeighted方法進(jìn)行圖像相減 addWeighted(imag1, 1, imag2, -1, 0,result2); imshow("原圖1", imag1); imshow("原圖2", imag2); imshow("result1", result1); imshow("addWeighted", result2); waitKey(); return 0;}uchar toZero(uchar a){ if (a < 0) return 0; else return a;}運行結(jié)果為:

result1貌似有問題,需要進(jìn)一步進(jìn)行檢查。
3.圖像相乘
圖像的乘法運算就是將兩幅圖像對應(yīng)的灰度值或彩色分量進(jìn)行相乘。
乘運算的主要作用是抑制圖像的某些區(qū)域,掩膜值置為1,否則置為0。乘運算有時也被用來實現(xiàn)卷積或相關(guān)的運算。
以下為相關(guān)程序代碼。
//圖像的乘運算。//將兩幅圖像對應(yīng)的灰度值或彩色分量進(jìn)行相乘。#include <iostream>#include <opencv2/core/core.hpp>#include <opencv2/highgui/highgui.hpp>using namespace std;using namespace cv;int main(){ Mat imag1, imag2, result; imag1 = imread("1234.jpg"); imag2 = imread("2345.jpg"); result = imag1.clone(); int rowNumber = result.rows; int colNumber = result.cols; for (int i = 0; i < rowNumber; i++) { for (int j = 0; j < colNumber; j++) { result.at<Vec3b>(i, j)[0] = (imag1.at<Vec3b>(i, j)[0] * imag2.at<Vec3b>(i, j)[0]) % 256; result.at<Vec3b>(i, j)[1] = (imag1.at<Vec3b>(i, j)[1] * imag2.at<Vec3b>(i, j)[1]) % 256; result.at<Vec3b>(i, j)[2] = (imag1.at<Vec3b>(i, j)[2] * imag2.at<Vec3b>(i, j)[2]) % 256; } } imshow("原圖1", imag1); imshow("原圖2", imag2); imshow("相乘后的圖像", result); waitKey(); return 0;}實驗的結(jié)果如下:
4.圖像相除
圖像除運算就是兩幅圖像對應(yīng)像素的灰度值或彩色分量進(jìn)行相除。
簡單的出運算可以用于改變圖像的灰度級
以下為代碼部分
//圖像的除法運算//就是講兩幅圖像的對應(yīng)像素的灰度值或彩色分量進(jìn)行相除。//簡單的除運算可以用來改變圖像的灰度級。#include <iostream>#include <opencv2/core/core.hpp>#include <opencv2/highgui/highgui.hpp>using namespace std;using namespace cv;int main(){ Mat imag1, imag2, result; imag2 = imread("1234.jpg"); imag1 = imread("2345.jpg"); result = imag1.clone(); int rowNumber = result.rows; int colNumber = result.cols; for (int i = 0; i < rowNumber; i++) { for (int j = 0; j < colNumber; j++) { result.at<Vec3b>(i, j)[0] = (imag1.at<Vec3b>(i, j)[0] * 1.0) / imag2.at<Vec3b>(i, j)[0]; result.at<Vec3b>(i, j)[1] = (imag1.at<Vec3b>(i, j)[1] * 1.0) / imag2.at<Vec3b>(i, j)[1]; result.at<Vec3b>(i, j)[2] = (imag1.at<Vec3b>(i, j)[2] * 1.0) / imag2.at<Vec3b>(i, j)[2]; } } imshow("原圖1", imag1); imshow("原圖2", imag2); imshow("相除后的圖像", result); waitKey(); return 0;}
新聞熱點
疑難解答