1. 程式人生 > >基於OpenCV的三種光流演算法實現原始碼及測試結果

基於OpenCV的三種光流演算法實現原始碼及測試結果

本文包括基於OpenCV三種光流演算法的實現原始碼及測試結果。具體為HS演算法,LK演算法,和ctfLK演算法,演算法的原實現作者是Eric Yuan,這裡是作者的部落格主頁:http://eric-yuan.me。本文對這三種光流演算法進行了相關除錯及結果驗證,供大家參考。

1. 第一種:HS光流法(作者HORN 和SCHUNCK)

#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <math.h>
#include <fstream>
#include <iostream>

using namespace cv;
using namespace std;

#define ATD at<double>
#define elif else if

#ifndef bool
#define bool int
#define false ((bool)0)
#define true  ((bool)1)
#endif


Mat get_fx(Mat &src1, Mat &src2){
	Mat fx;
	Mat kernel = Mat::ones(2, 2, CV_64FC1);
	kernel.ATD(0, 0) = -1.0;
	kernel.ATD(1, 0) = -1.0;

	Mat dst1, dst2;
	filter2D(src1, dst1, -1, kernel);
	filter2D(src2, dst2, -1, kernel);

	fx = dst1 + dst2;
	return fx;
}

Mat get_fy(Mat &src1, Mat &src2){
	Mat fy;
	Mat kernel = Mat::ones(2, 2, CV_64FC1);
	kernel.ATD(0, 0) = -1.0;
	kernel.ATD(0, 1) = -1.0;

	Mat dst1, dst2;
	filter2D(src1, dst1, -1, kernel);
	filter2D(src2, dst2, -1, kernel);

	fy = dst1 + dst2;
	return fy;
}

Mat get_ft(Mat &src1, Mat &src2){
	Mat ft;
	Mat kernel = Mat::ones(2, 2, CV_64FC1);
	kernel = kernel.mul(-1);

	Mat dst1, dst2;
	filter2D(src1, dst1, -1, kernel);
	kernel = kernel.mul(-1);
	filter2D(src2, dst2, -1, kernel);

	ft = dst1 + dst2;
	return ft;
}

bool isInsideImage(int y, int x, Mat &m){
	int width = m.cols;
	int height = m.rows;
	if (x >= 0 && x < width && y >= 0 && y < height) return true;
	else return false;
}

double get_Average4(Mat &m, int y, int x){
	if (x < 0 || x >= m.cols) return 0;
	if (y < 0 || y >= m.rows) return 0;

	double val = 0.0;
	int tmp = 0;
	if (isInsideImage(y - 1, x, m)){
		++tmp;
		val += m.ATD(y - 1, x);
	}
	if (isInsideImage(y + 1, x, m)){
		++tmp;
		val += m.ATD(y + 1, x);
	}
	if (isInsideImage(y, x - 1, m)){
		++tmp;
		val += m.ATD(y, x - 1);
	}
	if (isInsideImage(y, x + 1, m)){
		++tmp;
		val += m.ATD(y, x + 1);
	}
	return val / tmp;
}

Mat get_Average4_Mat(Mat &m){
	Mat res = Mat::zeros(m.rows, m.cols, CV_64FC1);
	for (int i = 0; i < m.rows; i++){
		for (int j = 0; j < m.cols; j++){
			res.ATD(i, j) = get_Average4(m, i, j);
		}
	}
	return res;
}

void saveMat(Mat &M, string s){
	s += ".txt";
	FILE *pOut = fopen(s.c_str(), "w+");
	for (int i = 0; i<M.rows; i++){
		for (int j = 0; j<M.cols; j++){
			fprintf(pOut, "%lf", M.ATD(i, j));
			if (j == M.cols - 1) fprintf(pOut, "\n");
			else fprintf(pOut, " ");
		}
	}
	fclose(pOut);
}

void getHornSchunckOpticalFlow(Mat img1, Mat img2){

	double lambda = 0.05;
	Mat u = Mat::zeros(img1.rows, img1.cols, CV_64FC1);
	Mat v = Mat::zeros(img1.rows, img1.cols, CV_64FC1);

	Mat fx = get_fx(img1, img2);
	Mat fy = get_fy(img1, img2);
	Mat ft = get_ft(img1, img2);

	int i = 0;
	double last = 0.0;
	while (1){
		Mat Uav = get_Average4_Mat(u);
		Mat Vav = get_Average4_Mat(v);
		Mat P = fx.mul(Uav) + fy.mul(Vav) + ft;
		Mat D = fx.mul(fx) + fy.mul(fy) + lambda;
		Mat tmp;
		divide(P, D, tmp);
		Mat utmp, vtmp;
		utmp = Uav - fx.mul(tmp);
		vtmp = Vav - fy.mul(tmp);
		Mat eq = fx.mul(utmp) + fy.mul(vtmp) + ft;
		double thistime = mean(eq)[0];
		cout << "i = " << i << ", mean = " << thistime << endl;
		if (i != 0 && fabs(last) <= fabs(thistime)) break;
		i++;
		last = thistime;
		u = utmp;
		v = vtmp;
	}
	saveMat(u, "U");
	saveMat(v, "V");

	imshow("U", u); 
	imshow("v", v);
	waitKey(20000);

}



int main(){

	Mat img1 = imread("table1.jpg", 0);
	Mat img2 = imread("table2.jpg", 0);
	
	img1.convertTo(img1, CV_64FC1, 1.0 / 255, 0);
	img2.convertTo(img2, CV_64FC1, 1.0 / 255, 0);

	getHornSchunckOpticalFlow(img1, img2);

	//    waitKey(0);

	return 0;
}


1  HS光流法原始影象(之一)


2HS光流法計算結果:U

3 HS光流法計算結果:V

1. 第二種:LK光流法(作者LUCAS 和KANADE)


#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <math.h>
#include <fstream>
#include <iostream>

using namespace cv;
using namespace std;

#define ATD at<double>
#define elif else if

#ifndef bool
#define bool int
#define false ((bool)0)
#define true  ((bool)1)
#endif


Mat get_fx(Mat &src1, Mat &src2){
	Mat fx;
	Mat kernel = Mat::ones(2, 2, CV_64FC1);
	kernel.ATD(0, 0) = -1.0;
	kernel.ATD(1, 0) = -1.0;

	Mat dst1, dst2;
	filter2D(src1, dst1, -1, kernel);
	filter2D(src2, dst2, -1, kernel);

	fx = dst1 + dst2;
	return fx;
}

Mat get_fy(Mat &src1, Mat &src2){
	Mat fy;
	Mat kernel = Mat::ones(2, 2, CV_64FC1);
	kernel.ATD(0, 0) = -1.0;
	kernel.ATD(0, 1) = -1.0;

	Mat dst1, dst2;
	filter2D(src1, dst1, -1, kernel);
	filter2D(src2, dst2, -1, kernel);

	fy = dst1 + dst2;
	return fy;
}

Mat get_ft(Mat &src1, Mat &src2){
	Mat ft;
	Mat kernel = Mat::ones(2, 2, CV_64FC1);
	kernel = kernel.mul(-1);

	Mat dst1, dst2;
	filter2D(src1, dst1, -1, kernel);
	kernel = kernel.mul(-1);
	filter2D(src2, dst2, -1, kernel);

	ft = dst1 + dst2;
	return ft;
}

bool isInsideImage(int y, int x, Mat &m){
	int width = m.cols;
	int height = m.rows;
	if (x >= 0 && x < width && y >= 0 && y < height) return true;
	else return false;
}

double get_Sum9(Mat &m, int y, int x){
	if (x < 0 || x >= m.cols) return 0;
	if (y < 0 || y >= m.rows) return 0;

	double val = 0.0;
	int tmp = 0;
	if (isInsideImage(y - 1, x - 1, m)){
		++tmp;
		val += m.ATD(y - 1, x - 1);
	}
	if (isInsideImage(y - 1, x, m)){
		++tmp;
		val += m.ATD(y - 1, x);
	}
	if (isInsideImage(y - 1, x + 1, m)){
		++tmp;
		val += m.ATD(y - 1, x + 1);
	}
	if (isInsideImage(y, x - 1, m)){
		++tmp;
		val += m.ATD(y, x - 1);
	}
	if (isInsideImage(y, x, m)){
		++tmp;
		val += m.ATD(y, x);
	}
	if (isInsideImage(y, x + 1, m)){
		++tmp;
		val += m.ATD(y, x + 1);
	}
	if (isInsideImage(y + 1, x - 1, m)){
		++tmp;
		val += m.ATD(y + 1, x - 1);
	}
	if (isInsideImage(y + 1, x, m)){
		++tmp;
		val += m.ATD(y + 1, x);
	}
	if (isInsideImage(y + 1, x + 1, m)){
		++tmp;
		val += m.ATD(y + 1, x + 1);
	}
	if (tmp == 9) return val;
	else return m.ATD(y, x) * 9;
}

Mat get_Sum9_Mat(Mat &m){
	Mat res = Mat::zeros(m.rows, m.cols, CV_64FC1);
	for (int i = 1; i < m.rows - 1; i++){
		for (int j = 1; j < m.cols - 1; j++){
			res.ATD(i, j) = get_Sum9(m, i, j);
		}
	}
	return res;
}

void saveMat(Mat &M, string s){
	s += ".txt";
	FILE *pOut = fopen(s.c_str(), "w+");
	for (int i = 0; i<M.rows; i++){
		for (int j = 0; j<M.cols; j++){
			fprintf(pOut, "%lf", M.ATD(i, j));
			if (j == M.cols - 1) fprintf(pOut, "\n");
			else fprintf(pOut, " ");
		}
	}
	fclose(pOut);
}

void getLucasKanadeOpticalFlow(Mat &img1, Mat &img2, Mat &u, Mat &v){

	Mat fx = get_fx(img1, img2);
	Mat fy = get_fy(img1, img2);
	Mat ft = get_ft(img1, img2);

	Mat fx2 = fx.mul(fx);
	Mat fy2 = fy.mul(fy);
	Mat fxfy = fx.mul(fy);
	Mat fxft = fx.mul(ft);
	Mat fyft = fy.mul(ft);

	Mat sumfx2 = get_Sum9_Mat(fx2);
	Mat sumfy2 = get_Sum9_Mat(fy2);
	Mat sumfxft = get_Sum9_Mat(fxft);
	Mat sumfxfy = get_Sum9_Mat(fxfy);
	Mat sumfyft = get_Sum9_Mat(fyft);

	Mat tmp = sumfx2.mul(sumfy2) - sumfxfy.mul(sumfxfy);
	u = sumfxfy.mul(sumfyft) - sumfy2.mul(sumfxft);
	v = sumfxft.mul(sumfxfy) - sumfx2.mul(sumfyft);
	divide(u, tmp, u);
	divide(v, tmp, v);

	    saveMat(u, "U");
	    saveMat(v, "V");   
	
           imshow("U", u);
	   imshow("V", v);
	   waitKey(2000);
}



int main(){

	Mat img1 = imread("car1.jpg", 0);
	Mat img2 = imread("car2.jpg", 0);
	

	img1.convertTo(img1, CV_64FC1, 1.0 / 255, 0);
	img2.convertTo(img2, CV_64FC1, 1.0 / 255, 0);


	Mat u = Mat::zeros(img1.rows, img1.cols, CV_64FC1);
	Mat v = Mat::zeros(img1.rows, img1.cols, CV_64FC1);

	getLucasKanadeOpticalFlow(img1, img2, u, v);

	cout << "done" << endl;
		
	return 0;
}


4 LK光流法原始影象(之一)


5 LK光流法計算結果:U


6 LK光流法計算結果:V


1. 第三種:ctfLK光流法(LK光流法的Coarse to fine版本

#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <math.h>
#include <fstream>
#include <iostream>

using namespace cv;
using namespace std;

#define ATD at<double>
#define ATF at<float>
#define elif else if

#ifndef bool
#define bool int
#define false ((bool)0)
#define true  ((bool)1)
#endif

Mat get_fx(Mat &src1, Mat &src2){
	Mat fx;
	Mat kernel = Mat::ones(2, 2, CV_64FC1);
	kernel.ATD(0, 0) = -1.0;
	kernel.ATD(1, 0) = -1.0;

	Mat dst1, dst2;
	filter2D(src1, dst1, -1, kernel);
	filter2D(src2, dst2, -1, kernel);

	fx = dst1 + dst2;
	return fx;
}

Mat get_fy(Mat &src1, Mat &src2){
	Mat fy;
	Mat kernel = Mat::ones(2, 2, CV_64FC1);
	kernel.ATD(0, 0) = -1.0;
	kernel.ATD(0, 1) = -1.0;

	Mat dst1, dst2;
	filter2D(src1, dst1, -1, kernel);
	filter2D(src2, dst2, -1, kernel);

	fy = dst1 + dst2;
	return fy;
}

Mat get_ft(Mat &src1, Mat &src2){
	Mat ft;
	Mat kernel = Mat::ones(2, 2, CV_64FC1);
	kernel = kernel.mul(-1);

	Mat dst1, dst2;
	filter2D(src1, dst1, -1, kernel);
	kernel = kernel.mul(-1);
	filter2D(src2, dst2, -1, kernel);

	ft = dst1 + dst2;
	return ft;
}

bool isInsideImage(int y, int x, Mat &m){
	int width = m.cols;
	int height = m.rows;
	if (x >= 0 && x < width && y >= 0 && y < height) return true;
	else return false;
}

double get_Sum9(Mat &m, int y, int x){
	if (x < 0 || x >= m.cols) return 0;
	if (y < 0 || y >= m.rows) return 0;

	double val = 0.0;
	int tmp = 0;
	for (int i = -1; i <= 1; i++){
		for (int j = -1; j <= 1; j++){
			if (isInsideImage(y + i, x + j, m)){
				++tmp;
				val += m.ATD(y + i, x + j);
			}
		}
	}
	if (tmp == 9) return val;
	else return m.ATD(y, x) * 9;
}

Mat get_Sum9_Mat(Mat &m){
	Mat res = Mat::zeros(m.rows, m.cols, CV_64FC1);
	for (int i = 1; i < m.rows - 1; i++){
		for (int j = 1; j < m.cols - 1; j++){
			res.ATD(i, j) = get_Sum9(m, i, j);
		}
	}
	return res;
}

void saveMat(Mat &M, string s){
	s += ".txt";
	FILE *pOut = fopen(s.c_str(), "w+");
	for (int i = 0; i<M.rows; i++){
		for (int j = 0; j<M.cols; j++){
			fprintf(pOut, "%lf", M.ATD(i, j));
			if (j == M.cols - 1) fprintf(pOut, "\n");
			else fprintf(pOut, " ");
		}
	}
	fclose(pOut);
}

void getLucasKanadeOpticalFlow(Mat &img1, Mat &img2, Mat &u, Mat &v){

	Mat fx = get_fx(img1, img2);
	Mat fy = get_fy(img1, img2);
	Mat ft = get_ft(img1, img2);

	Mat fx2 = fx.mul(fx);
	Mat fy2 = fy.mul(fy);
	Mat fxfy = fx.mul(fy);
	Mat fxft = fx.mul(ft);
	Mat fyft = fy.mul(ft);

	Mat sumfx2 = get_Sum9_Mat(fx2);
	Mat sumfy2 = get_Sum9_Mat(fy2);
	Mat sumfxft = get_Sum9_Mat(fxft);
	Mat sumfxfy = get_Sum9_Mat(fxfy);
	Mat sumfyft = get_Sum9_Mat(fyft);

	Mat tmp = sumfx2.mul(sumfy2) - sumfxfy.mul(sumfxfy);
	u = sumfxfy.mul(sumfyft) - sumfy2.mul(sumfxft);
	v = sumfxft.mul(sumfxfy) - sumfx2.mul(sumfyft);
	divide(u, tmp, u);
	divide(v, tmp, v);
}

vector<Mat> getGaussianPyramid(Mat &img, int nLevels){
	vector<Mat> pyr;
	pyr.push_back(img);
	for (int i = 0; i < nLevels - 1; i++){
		Mat tmp;
		pyrDown(pyr[pyr.size() - 1], tmp);
		pyr.push_back(tmp);
	}
	return pyr;
}

void coarseToFineEstimation(Mat &img1, Mat &img2, Mat &u, Mat &v, int nLevels){

	vector<Mat> pyr1 = getGaussianPyramid(img1, nLevels);
	vector<Mat> pyr2 = getGaussianPyramid(img2, nLevels);
	Mat upu, upv;
	for (int i = nLevels - 1; i >= 0; i--){

		Mat tmpu = Mat::zeros(pyr1[i].rows, pyr1[i].cols, CV_64FC1);
		Mat tmpv = Mat::zeros(pyr2[i].rows, pyr2[i].cols, CV_64FC1);
		getLucasKanadeOpticalFlow(pyr1[i], pyr2[i], tmpu, tmpv);
		if (i != nLevels - 1){
			tmpu += upu;
			tmpv += upv;
		}
		if (i == 0){
			u = tmpu;
			v = tmpv;
			return;
		}
		pyrUp(tmpu, upu);
		pyrUp(tmpv, upv);

		Mat map1(upu.size(), CV_32FC2);
		Mat map2(upu.size(), CV_32FC2);
		for (int y = 0; y < map1.rows; ++y){
			for (int x = 0; x < map1.cols; ++x){
				Point2f f = Point2f((float)(upu.ATD(y, x)), (float)(upv.ATD(y, x)));
				map1.at<Point2f>(y, x) = Point2f(x + f.x / 2, y + f.y / 2);
				map2.at<Point2f>(y, x) = Point2f(x - f.x / 2, y - f.y / 2);
			}
		}
		Mat warped1, warped2;
		remap(pyr1[i - 1], warped1, map1, cv::Mat(), INTER_LINEAR);
		remap(pyr2[i - 1], warped2, map2, cv::Mat(), INTER_LINEAR);
		warped1.copyTo(pyr1[i - 1]);
		warped2.copyTo(pyr2[i - 1]);
	}
}

int getMaxLayer(Mat &img){
	int width = img.cols;
	int height = img.rows;
	int res = 1;
	int p = 1;
	while (1){
		int tmp = pow(2, p);
		if (width % tmp == 0) ++p;
		else break;
	}
	res = p;
	p = 1;
	while (1){
		int tmp = pow(2, p);
		if (height % tmp == 0) ++p;
		else break;
	}
	res = res < p ? res : p;
	return res;
}

int main(){

	Mat ori1 = imread("table1.jpg", 0);
	Mat ori2 = imread("table2.jpg", 0);
	Mat img1 = ori1(Rect(0, 0, 640, 448));
	Mat img2 = ori2(Rect(0, 0, 640, 448));


	int maxLayer = getMaxLayer(img1);
	cout << img1.rows << ", " << img1.cols << ", Max layer = " << maxLayer << endl;


	img1.convertTo(img1, CV_64FC1, 1.0 / 255, 0);
	img2.convertTo(img2, CV_64FC1, 1.0 / 255, 0);


	Mat u = Mat::zeros(img1.rows, img1.cols, CV_64FC1);
	Mat v = Mat::zeros(img1.rows, img1.cols, CV_64FC1);
	Mat u2 = Mat::zeros(img1.rows, img1.cols, CV_64FC1);
	Mat v2 = Mat::zeros(img1.rows, img1.cols, CV_64FC1);

	if (maxLayer >= 1){
		coarseToFineEstimation(img1, img2, u, v, maxLayer);
		saveMat(u, "U");
		saveMat(v, "V");
	}

	getLucasKanadeOpticalFlow(img1, img2, u2, v2);
	saveMat(u2, "U2");
	saveMat(v2, "V2");

	imshow("U2", u2);
	imshow("v2", v2);
	
	waitKey(20000);

	return 0;
}


7 ctfLK光流法測試原始影象(之一)


8 ctfLK光流法計算結果:U2


9 ctfLK光流法計算結果:v2


相關推薦

基於OpenCV演算法實現原始碼測試結果

本文包括基於OpenCV的三種光流演算法的實現原始碼及測試結果。具體為HS演算法,LK演算法,和ctfLK演算法,演算法的原實現作者是Eric Yuan,這裡是作者的部落格主頁:http://eric-yuan.me。本文對這三種光流演算法進行了相關除錯及結果驗證,供大家

解決尋找第K小元素問題——不同的演算法實現

問題描述:在一個序列裡找出第K小元素 以下程式基於函式 int select_kth_smallest(list q, int k) 實現 :返回向量q中第k最小元的函式 演算法一: 基於氣泡排序思想,暴力求解: 基本思路:要求找出第k個最小元素,可以通過在序

玩轉OpenCV 4.0(一):呼叫Dis演算法示例

玩轉OpenCV 4.0(一):呼叫Dis光流演算法示例 呼叫DIS光流的原始碼如下: 對應CMakelists如下: 呼叫DIS光流的原始碼如下: #include "opencv2/core/utility.hpp"

Java實現二叉樹遍歷演算法

</pre><p></p><p>參考網上一些資料測試整理了一下二叉樹遍歷的Java實現程式碼。</p>二叉樹三種遍歷方式:先序遍歷、中序遍歷、後序遍歷。<p>首先定義二叉樹類:</p>&l

java實現二叉樹的遍歷演算法(遞迴)

一,定義一個節點類: package test; public class Node { private int data; private Node left; private Node right; public Node(int data) { thi

常用排序演算法(冒泡、選擇、快速)的Java實現

       學習Java有一陣子了,現在還處於比較初級的水平,能夠把簡單的程式寫對就不錯了,更不用談現在能夠拿Java做什麼了。        學完了兩段網路視訊課程,接下來找本書簡單看看。只要有了一個初步的認識,接下來的東西應該可以更加順利一些。學習程式設計最好的方法就

鳶尾花聚類演算法(K-means,AGNES,DBScan)的python實現

一.分散性聚類(kmeans) 演算法流程: 1.選擇聚類的個數k. 2.任意產生k個聚類,然後確定聚類中心,或者直接生成k箇中心。 3.對每個點確定其聚類中心點。 4.再計算其聚類新中心。 5.重複以上步驟直到滿足收斂要求。(通常就是確定的中心點不再改變。

目標檢測法(二):opencv下的L-K演算法

後續將簡單介紹光流法的一些簡單實現包,包括opencv下的光流演算法與matlab下的光流演算法。該節主要介紹opencv下的光流實現。 Opencv的光流實現由好幾個方法可以(也就是說有好幾個函式可以用),每個函式當然也對應著不同的原理,那麼它的效果以及演算

快速排序演算法實現(遞迴演算法、非遞迴演算法路劃分快速排序)

快速排序的三個步驟: 1、分解:將陣列A[l...r]劃分成兩個(可能空)子陣列A[l...p-1]和A[p+1...r],使得A[l...p-1]中的每個元素都小於等於A(p),而且,小於等於A[p

OpenCV 演算法加速---使用GPU來計算

一、依賴項 OpenCV 2.4.13.x + CUDA 8.0 OpenCV 3.2.0及以上 + CUDA 8.0 OpenCV 3.4.x + CUDA 9.1 OpenCV編譯時,需要新增CUDA 支援。安裝CUDA 以及OpenCV,可參考我的另外兩篇部落格

DES/3DES/AES 對稱加密演算法在 Java 中的實現

有兩句話是這麼說的:1)演算法和資料結構就是程式設計的一個重要部分,你若失掉了演算法和資料結構,你就把一切都失掉了。2)程式設計就是演算法和資料結構,演算法和資料結構是程式設計的靈魂。注意,這可不是我說的,是無數程式設計師總結的,話說的很實在也很精闢,若想長久可持續發展,多研

nginx虛擬主機模式的簡單實現

_for nod send nop request user 模式 -s hit main配置段: user nginx; #指定用於運行worker進程的用戶和組 worker_processes 4; #worker的進程數;通常應該為CPU的核心數或核心數減1

035捷聯慣導中姿態更新演算法說明

看到了不同的姿態更新演算法,很迷惑,陷入了誰相對於誰的思考中。翻翻嚴老師部落格,貼出來如下: 原文地址:http://blog.sina.com.cn/s/blog_40edfdc90102v6il.html#cmt_556E9C77-7F000001-41D46DB9-790-8

Lucas–Kanade演算法學習

Lucas–Kanade光流演算法是一種兩幀差分的光流估計演算法。它由Bruce D. Lucas 和 Takeo Kanade提出。         光流(Optical flow or optic

opencv線性濾波的綜合使用

本文程式碼來源於https://blog.csdn.net/poem_qianmo/article/details/22745559,在上一篇文章的基礎上增加了進度條的支援,可以更加直觀的看出濾波的效果 #include "widget.h" #include <QApplication&

jvm 垃圾回收演算法:標記-清除、複製演算法、標記-整理

標記-清除:先標記出GC Roots能關聯到的物件,然後清除這些被標記的物件,剩下的就是存活的物件了。 缺點: 1、清除需要被清理的物件後剩下的記憶體都是破碎的,如果要建立大物件,可能會因為找不到足夠的記憶體而再次觸發垃圾收集。 2、標記和清除的效率相對於其他演算法來說都不高,標記的原理

java代理模式的實現

1、什麼是代理模式 代理模式:就是為其他物件提供一種代理以控制對這個物件的訪問。 代理可以在不改動目標物件的基礎上,增加其他額外的功能(擴充套件功能)。 舉個例子來說明代理的作用: 一般我們想邀請明星來當我們的代言人,我們並不能直接聯絡到明星,而是通過其經紀人,來告訴經紀人我們需要

演算法分析】Lucas–Kanade演算法

作者:[email protected]簡介:在計算機視覺中,Lucas–Kanade光流演算法是一種兩幀差分的光流估計演算法。它由Bruce D. Lucas 和 Takeo Kanade提出。光流的概念:(Optical flow or optic flow)它是一種運動模式,這種運動模式指的是

基於聚類(Kmeans)演算法實現客戶價值分析系統(電信運營商)

開發環境 jupyter notebook 一、電信運營商–客戶價值分析 從客戶需求出發,瞭解客戶需要什麼,他們有怎麼樣的特徵, 電信運營商為客戶設定不同的優惠套餐 爭取更多的使用者:推出不同的優

深度學習()——tiny YOLO演算法實現實時目標檢測(tensorflow實現

一、背景介紹 YOLO演算法全稱You Only Look Once,是Joseph Redmon等人於15年3月發表的一篇文章。本實驗目標為實現YOLO演算法,借鑑了一部分材料,最終實現了輕量級的簡化版YOLO——tiny YOLO,其優勢在於實現簡單,目標檢測迅速。 [1]文章連結:ht