1. 程式人生 > >OpenCV數字影象處理十一:利用分段線性化處理影象 在某些情況效果很實用

OpenCV數字影象處理十一:利用分段線性化處理影象 在某些情況效果很實用

分段線性變換

分段線性變換也叫做灰度線性拉伸,常用的是分三段分線性變換。如下圖:


圖中對灰度區間[a,b]進行了擴充套件,而灰度區間[0, a]和[b, Mf]收到了壓縮。通過細心調整折線拐點的位置及控制分段直線的斜率,可對任意灰度區間進行擴充套件和壓縮。、本文就是基於這做的影象增強。

#include "cxcore.h"
#include <cv.h>
#include <highgui.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>


#include <omp.h>
#include <windows.h>
LARGE_INTEGER m_liPerfFreq;
LARGE_INTEGER m_liPerfStart;
LARGE_INTEGER liPerfNow;
double dfTim;


void getStartTime()
{
QueryPerformanceFrequency(&m_liPerfFreq);
QueryPerformanceCounter(&m_liPerfStart);
}


void getEndTime()
{
QueryPerformanceCounter(&liPerfNow);
dfTim=( ((liPerfNow.QuadPart - m_liPerfStart.QuadPart) * 1000.0f)/m_liPerfFreq.QuadPart);
}


//定義折線變換的座標
const CvPoint p1 = cvPoint(46, 0);
const CvPoint p2 = cvPoint(200, 255);


const bool showSteps = true;


const int NumVideo = 1; 


using namespace cv;


int main(void)
{
CvCapture* capture;
IplImage* src;;


char *video_name = NULL;
video_name = (char*)malloc(50*sizeof(char)); 
for(int jj=1; jj<=NumVideo; jj++)
{
printf("處理第%d段視訊\n",jj);

//讀取d盤下video目錄裡的1.avi檔案。
sprintf_s(video_name, 50, "D:\\video\\%d.avi",1);


capture = cvCaptureFromAVI(video_name);


if( capture == NULL )
{
printf("視訊檔案開啟失敗!!\n");
return -1;
}


//定義和初始化變數

src = cvQueryFrame(capture);
cvNamedWindow("source Image",CV_WINDOW_AUTOSIZE);
cvShowImage("source Image",src);}


for(int i=0;i<130;i++)
src = cvQueryFrame(capture); //獲取一幀圖片

while( 1 )
{
//獲取空格鍵值,並置位摳圖標誌位flag
int c = cvWaitKey(0);
if((char)c==(char)32)
{
src = cvQueryFrame(capture); //獲取一幀圖片
// image = imread("..\\image4\\test.bmp");


if(! src->imageData ) // Check for invalid input
{
printf("Could not open or find the image");
return -1;
} 


// char*filename="1 (1).bmp";
// IplImage*src=cvLoadImage(filename,0);
IplImage* srcTemp = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1);


getStartTime();
if(src->nChannels == 3){
cvCvtColor(src,srcTemp,CV_BGR2GRAY);
}


cvSaveImage("test.bmp",src);


// cvEqualizeHist(srcTemp,srcTemp);
// IplImage*image=cvLoadImage(filename,0);
IplImage*image=cvCloneImage(srcTemp);




//----------************--------------------//
//顯示處理前的影象的直方圖
Mat resouce, dst;
/// Load image
resouce = Mat(src);
// resouce = cvQueryFrame(capture);
if( !resouce.data )
{ return -1; }
/// Separate the image in 3 places ( B, G and R )
vector<Mat> bgr_planes;
split( resouce, bgr_planes );
/// Establish the number of bins
int histSize = 256;
/// Set the ranges ( for B,G,R) )
float range[] = { 0, 256 } ;
const float* histRange = { range };
bool uniform = true; bool accumulate = false;
Mat b_hist, g_hist, r_hist;
/// Compute the histograms:
calcHist( &bgr_planes[0], 1, 0, Mat(), b_hist, 1, &histSize, &histRange, uniform, accumulate );
calcHist( &bgr_planes[1], 1, 0, Mat(), g_hist, 1, &histSize, &histRange, uniform, accumulate );
calcHist( &bgr_planes[2], 1, 0, Mat(), r_hist, 1, &histSize, &histRange, uniform, accumulate );
// Draw the histograms for B, G and R
int hist_w = 512; int hist_h = 400;
int bin_w = cvRound( (double) hist_w/histSize );
Mat histImage( hist_h, hist_w, CV_8UC3, Scalar( 0,0,0) );
/// Normalize the result to [ 0, histImage.rows ]
normalize(b_hist, b_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() );
normalize(g_hist, g_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() );
normalize(r_hist, r_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() );
/// Draw for each channel
for( int i = 1; i < histSize; i++ )
{
line( histImage, Point( bin_w*(i-1), hist_h - cvRound(b_hist.at<float>(i-1)) ) ,
Point( bin_w*(i), hist_h - cvRound(b_hist.at<float>(i)) ),
Scalar( 255, 0, 0), 2, 8, 0 );
line( histImage, Point( bin_w*(i-1), hist_h - cvRound(g_hist.at<float>(i-1)) ) ,
Point( bin_w*(i), hist_h - cvRound(g_hist.at<float>(i)) ),
Scalar( 0, 255, 0), 2, 8, 0 );
line( histImage, Point( bin_w*(i-1), hist_h - cvRound(r_hist.at<float>(i-1)) ) ,
Point( bin_w*(i), hist_h - cvRound(r_hist.at<float>(i)) ),
Scalar( 0, 0, 255), 2, 8, 0 );
}


/// Display
namedWindow("calcHist Demo", CV_WINDOW_AUTOSIZE );
imshow("calcHist Demo", histImage );
//-----------------------**************---------------------//

//對影象進行分段線性變化處理:
for( int y=0; y<image->height; y++ ) {
uchar* pDataSrc = (uchar*) (srcTemp->imageData + y * srcTemp->widthStep );
uchar* pDataImage = (uchar*) (image->imageData + y * image->widthStep );
for( int x=0; x<image->width; x++ ) {
if(pDataSrc[x]<=p1.x)
pDataImage[x]=(int)((p1.y/p1.x)*pDataSrc[x]);
else if(pDataSrc[x]>=p2.x)
// pDataImage[x]=(int)((p2.y-p1.y)/(p2.x-p1.x)*pDataSrc[x])+p1.y;
pDataImage[x]=p1.y;
else
// pDataImage[x]=(int)(p1.y);
pDataImage[x]=(int)((p2.y-p1.y)/(p2.x-p1.x)*pDataSrc[x])+p1.y;


if(pDataImage[x]>255)
pDataImage[x]=255;


}
}
// cvNormalize(image,image,255,0,CV_C,NULL);


if(showSteps){
cvShowImage("source Image",src);}
if(showSteps){
cvNamedWindow("gray Image",CV_WINDOW_AUTOSIZE);
cvShowImage("gray Image",image);}



//threshold 
IplImage* gray=cvCloneImage(image);
// cvThreshold(image,gray,101,255,CV_THRESH_OTSU+CV_THRESH_BINARY);
int blockSize = 19;
int constValue = 3;
cvAdaptiveThreshold(image,gray,255, CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY_INV, blockSize, constValue);


cvSmooth(gray,gray,CV_MEDIAN,5);

if(showSteps){
cvNamedWindow("threshold Image",CV_WINDOW_AUTOSIZE);
cvShowImage("threshold Image",gray);}


getEndTime();
printf("%f\n",dfTim);
cvWaitKey(0);
}

}
cvWaitKey(0);
}


相關推薦

OpenCV數字影象處理利用分段線性處理影象某些情況效果實用

分段線性變換 分段線性變換也叫做灰度線性拉伸,常用的是分三段分線性變換。如下圖: 圖中對灰度區間[a,b]進行了擴充套件,而灰度區間[0, a]和[b, Mf]收到了壓縮。通過細心調整折線拐點的位置及控制分段直線的斜率,可對任意灰度區間進行擴充套件和壓縮。、本文就是基

opencv學習筆記七影象修復

當我們的照片有劃痕或遭到人為的塗鴉(比如馬賽克)時, 如果我們想讓這些遭到破壞的圖片儘可能恢復到原樣,Opencv能幫我們做到嗎?答案是肯定的。 那麼影象修復技術的原理是什麼呢? 簡而言之,就是利用那些已經被破壞的區域的邊緣, 即邊緣的顏色和結構,根據這些影象留下的資訊去

OpenCV入門教程之】 形態學影象處理(二)開運算、閉運算、形態學梯度、頂帽、黑帽合輯

上篇文章中,我們重點了解了腐蝕和膨脹這兩種最基本的形態學操作,而運用這兩個基本操作,我們可以實現更高階的形態學變換。所以,本文的主角是OpenCV中的morphologyEx函式,它利用基本的膨脹和腐蝕技術,來執行更加高階的形態學變換,如開閉運算、形態學梯度、“頂帽”、“黑帽

Tensorflow深度學習之基礎影象處理

OpenCV是一個十分強大的視覺庫,tensorflow也提供了十分強大的圖片處理函式,下面是一個簡單的例子來說明使用tensorflow和opencv兩個工具進行深度學習程式的設計。 首先是使用的原始圖片: import tensorflow as

python實現opencv學習二影象的開閉操作

作用:刪除影象的小的干擾項原始碼如下:# -*- coding=GBK -*- import cv2 as cv #影象的開閉操作 def open_image(image): gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY

Python基礎教程筆記Python Number(數字)

顯示 sta ron nbsp num 下一個 組成 有效 位數 Python 支持四種不同的數值類型: 整型(Int) - 通常被稱為是整型或整數,是正或負整數,不帶小數點。 長整型(long integers) - 無限大小的整數,整數最後是一個大寫或小寫的L。

python+seleniumjQuery和js語法、js處理iframe python+seleniumjQuery和js語法、js處理iframe

python+selenium十一:jQuery和js語法、js處理iframe   selenium 執行jQuery/js語法 driver.execute_script(jQuery/js) 1、jQuery jQuery只支援css語法: jq

opencv學習(二圓檢測

檢測原理: 參考連結:https://www.cnblogs.com/ssyfj/p/9275977.html#一houghcircles方法                     

opencv學習筆記三Haar特徵與積分影象

一、 Haar特徵定義         Haar特徵是基於“塊”的特徵,也被稱為矩形特徵。Haar特徵(模板)分為三類:邊緣特徵、線性特徵、中心特徵和對角線特徵。特徵模板內有白色和黑色兩種矩形,並定義該模板的特徵值為白色矩形畫素和減去黑色矩形畫素和。Haar特徵值反映了影象

opencv學習筆記五基於分水嶺的影象分割

#include<opencv2\opencv.hpp> using namespace cv; using namespace std; int main(int arc, char** argv) { Mat src = imread("1.jpg");

opencv學習筆記五影象融合之背景替換

以證件照為例,圖片中有大部分為背景,先用kmeans對影象進行分割,可以得到背景的標籤,然後將影象分為前景和背景兩部分,非背景的都當作前景,顯示kmeans分割後的影象dst,將原影象前景賦給dst, 背景都設為0,得到kmeans分割後的影象如下,可看到邊緣處有一些小藍邊,

Java Web 學習筆記之RestEasy統一處理異常

JBoss RestEasy框架配置異常統一處理 前提 利用JBoss restEasy框架搭建的restful java web後臺應用 希望通過統一的方式對restful介面丟擲的異常進行

Python影象處理(7)利用輪廓分塊處理

快樂蝦歡迎轉載,但請保留作者資訊在得到綠色植物的前景影象後,我們希望能夠進一步標識出其中的棉花植株和雜草。測試影象仍然是它:首先要做的當然是對影象進行分割槽域處理。在上一步中我們得到了標識綠色植物的二值

tensorflow學習筆記用別人訓練好的模型來進行影象分類

谷歌在大型影象資料庫ImageNet上訓練好了一個Inception-v3模型,這個模型我們可以直接用來進來影象分類。下載完解壓後,得到幾個檔案:其中的classify_image_graph_def.pb 檔案就是訓練好的Inception-v3模型。imagenet_sy

Python3與OpenCV3.3 影象處理()--影象直方圖

一、什麼是影象直方圖 由於其計算代價較小,且具有影象平移、旋轉、縮放不變性等眾多優點,廣泛地應用於影象處理的各個領域,特別是灰度影象的閾值分割、基於顏色的影象檢索以及影象分類。 二、應用範圍

Spring Boot 2.X()全域性異常處理

前言 在 Java Web 系統開發中,不管是 Controller 層、Service 層還是 Dao 層,都有可能丟擲異常。如果在每個方法中加上各種 try catch 的異常處理程式碼,那樣會使程式碼非常繁瑣。在Spring MVC 中,我們可以將所有型別的異常處理從各個單獨的方法中解耦出來,進行異常資

Web前端面試指導()樣式導入有哪些方式?

web前端樣式導入方式linkimport使用方式link的使用[css] view plain copy <link href="index.css" rel="stylesheet"> import的使用[css] view plain copy <style type="text/c

【Java並發編程】之線程間通信中notify通知的遺漏(含代碼)

key wait title net fill article 返回 0ms 註意 轉載請註明出處:http://blog.csdn.net/ns_code/article/details/17228213 notify通知的遺漏很容易理解,即threadA還沒

【Java並發編程】之二並發新特性—阻塞隊列和阻塞棧(含代碼)

err 退出 link rac gb2312 com void throws pbo 轉載請註明出處:http://blog.csdn.net/ns_code/article/details/17511147 阻塞隊列 阻塞隊列是Java 5並發新特性中的內容

Office 365 系列之使用 Windows PowerShell 管理 O365 平臺

命令管理o365 命令管理office 365 正如之前我們說的,通過 O365 管理中心、Exchange 管理中心、Lync 管理中 心 SharePoint 管理中心能做的事情和能夠實現的需求是遠遠滿足不了客戶的時 間需求的。可以使用用於 Windows PowerShell 的 Azu