閾值化

對圖像中的三個同澳求和,然後在值爲100處度結果進行截斷


#include <stdio.h>
#include "opencv/cv.h"
#include "opencv/highgui.h"


void sum_rgb(IplImage* src, IplImage* dst)
{

    //Allocate individual image planes
    IplImage* r = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1);
    IplImage* g = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1);
    IplImage* b = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1);
    //Split image onto the  color planes
    cvSplit(src,r,g,b,NULL);
    //Temporary storage
    IplImage* s = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1);
    
    //add equally weighted rgb values
    cvAddWeighted(r,1./3.,g,1./3.,0.0,s);
    cvAddWeighted(s,2./3.,b,1./3.,0.0,s);

    //Truncate values above 100
    cvThreshold(s,dst,100,100,CV_THRESH_TRUNC);
    
    cvReleaseImage(&r);
    cvReleaseImage(&g);
    cvReleaseImage(&b);
    cvReleaseImage(&s);
   
}
int main(int argc,char** argv)
{
    cvNamedWindow(argv[1],1);
    
    IplImage* src = cvLoadImage(argv[1]);
    IplImage*dst = cvCreateImage(cvGetSize(src),src->depth,1);
    sum_rgb(src,dst);
    cvShowImage(argv[1],dst);
    while(1){
        if((cvWaitKey(10)&0x7f) == 27) break;    }
        
    cvDestroyWindow(argv[1]);
    
    cvReleaseImage(&src);
    cvReleaseImage(&dst);

    return 0;
}



CreateImage
創建頭並分配數據IplImage* cvCreateImage( CvSize size, int depth, int channels );
size
圖像寬、高.
depth
圖像元素的位深度,可以是下面的其中之一:
IPL_DEPTH_8U - 無符號 8 位整型
IPL_DEPTH_8S - 有符號 8 位整型
IPL_DEPTH_16U - 無符號 16 位整型
IPL_DEPTH_16S - 有符號 16 位整型
IPL_DEPTH_32S - 有符號 32 位整型
IPL_DEPTH_32F - 單精度浮點數
IPL_DEPTH_64F - 雙精度浮點數
channels
每個元素(像素)通道號.可以是 1, 2, 3 4.通道是交叉存取的,例如通常的彩色圖像數據
排列是:
b0 g0 r0 b1 g1 r1 ...
雖然通常 IPL 圖象格式可以存貯非交叉存取的圖像,並且一些 OpenCV 也能處理他, 但是
這個函數只能創建交叉存取圖像.函數 cvCreateImage 創建頭並分配數據,這個函數是下列的縮寫型式header = cvCreateImageHeader(size,depth,channels);cvCreateData(header);



AddWeighted
計算兩數組的加磅值的和void cvAddWeighted( const CvArr* src1, double alpha,const CvArr* src2, double beta,double gamma, CvArr* dst );
src1
第一個原數組.
alpha
第一個數組元素的磅值
src2
第二個原數組
beta
第二個數組元素的磅值
dst
輸出數組
gamma
作和合添加的數量。函數 cvAddWeighted 計算兩數組的加磅值的和:dst(I)=src1(I)*alpha+src2(I)*beta+gamma所有的數組必須的相同的類型相同的大小(或 ROI 大小)


Split
分割多通道數組成幾個單通道數組或者從數組中提取一個通道void cvSplit( const CvArr* src, CvArr* dst0, CvArr* dst1,CvArr* dst2, CvArr* dst3 );#define cvCvtPixToPlane cvSplit
src
原數組.
dst0...dst3
目標通道函數 cvSplit 分割多通道數組成分離的單通道數組 d。可獲得兩種操作模式 . 如果原數組有 N 通道且前 N 輸出數組非 NULL, 所有的通道都會被從原數組中提取,如果前 N個通道只有一個通道非 NULL 函數只提取該指定通道,否則會產生一個錯誤,餘下的通道(超過前 N 個通道的以上的)必須被設置成 NULL,對於設置了 COI 的 IplImage 結使 cvCopy 也可以從圖像中提取單通道。


Threshold
對數組元素進行固定閾值操作void cvThreshold( const CvArr* src, CvArr* dst, double threshold,double max_value, int threshold_type );
src
原始數組 (單通道, 8-比特 of 32-比特 浮點數).
dst
輸出數組,必須與 src 的類型一致,或者爲 8-比特.
threshold
閾值
max_value
使用 CV_THRESH_BINARY CV_THRESH_BINARY_INV 的最大值.
threshold_type
閾值類型 (見討論)函數 cvThreshold 對單通道數組應用固定閾值操作。該函數的典型應用是對灰度圖像進行閾值操作得到二值圖像。(cvCmpS 也可以達到此目的) 或者是去掉噪聲,例如過濾很小或很大象素值的圖像點。
本函數支持的對圖像取閾值的方法由 threshold_type 確定:

threshold_type=CV_THRESH_BINARY:dst(x,y) = max_value, if src(x,y)>threshold0, otherwisethreshold_type=CV_THRESH_BINARY_INV:dst(x,y) = 0, if src(x,y)>thresholdmax_value, otherwisethreshold_type=CV_THRESH_TRUNC:dst(x,y) = threshold, if src(x,y)>thresholdsrc(x,y), otherwisethreshold_type=CV_THRESH_TOZERO:dst(x,y) = src(x,y), if (x,y)>threshold0, otherwisethreshold_type=CV_THRESH_TOZERO_INV:dst(x,y) = 0, if src(x,y)>thresholdsrc(x,y), otherwise


下面是圖形化的閾值描述:


效果圖如下:








/*
比較自適應閥值和單一閥值
*/
#include <stdio.h>
#include "opencv/cv.h"
#include "opencv/highgui.h"
#include "math.h"

IplImage* Igray = 0,*It = 0, *Iat;

int main(int argc,char** argv)
{
    if(argc != 7){return -1;}
    
    double threshold = (double)atof(argv[1]);
    int threshold_type = atoi(argv[1]) ?  
                    CV_THRESH_BINARY : CV_THRESH_BINARY_INV;
    int adaptive_method = atoi(argv[3]) ? 
                    CV_ADAPTIVE_THRESH_MEAN_C : CV_ADAPTIVE_THRESH_GAUSSIAN_C;
                    
    int block_size = atoi(argv[4]);
    double offset = (double)atof(argv[5]);
    
    //Read in gray image
    if((Igray = cvLoadImage(argv[6],CV_LOAD_IMAGE_GRAYSCALE)) == 0){
        return -1;}
    
    It = cvCreateImage(cvSize(Igray->width,Igray->height),IPL_DEPTH_8U,1);
    Iat = cvCreateImage(cvSize(Igray->width,Igray->height),IPL_DEPTH_8U,1);
    
    cvThreshold(Igray,It,threshold,255,threshold_type);
    cvAdaptiveThreshold(Igray,Iat,255,adaptive_method,threshold_type,block_size,offset);
    
    cvNamedWindow("Raw",0);
    cvNamedWindow("Threshold",0);
    cvNamedWindow("Adaptive Threshold",0);
    
    cvShowImage("Raw",Igray);
    cvShowImage("Threshold",It);
    cvShowImage("Adaptive Threshold",Iat);
    
    cvWaitKey(0);
    
    cvReleaseImage(&Igray);
    cvReleaseImage(&It);
    cvReleaseImage(&Iat);
    cvDestroyAllWindows();
    
    return 0;
}



























發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章