發現了一個很棒的git,mark一下
https://github.com/android-nuc/StudyPath/blob/master/README.md
找到了一本書《opencv算法精解基于python和C++》
圖書館沒有啦不過下載了電子版
對算法進行了解析并且通過python和c++兩種語言實現
感覺挺棒的 學習一下試試看
看毛星云那本可以等看完這個再看
// ex2c++.cpp : 定義控制臺應用程序的入口點。
//
#include “stdafx.h”
#include<opencv2/core/core.hpp>
#include
using namespace cv;
int main()
{
//兩種定義Mat的方式
Mat m = Mat(Size(2, 3), CV_32FC(1));
Mat n = (Mat_(2, 3) << 1, 2, 3, 4, 5, 6);
std::cout <<"利用Size"<<"\n"<< m<<"\n";
std::cout <<"\n"<<"利用Mat_<int>"<<"\n"<< n<<"\n";
std::cout <<"\n"<< "行" << n.rows;
Size size = m.size();//獲取尺寸
std::cout <<"\n"<< "尺寸" << size;
std::cout << "\n" << "利用at/Point獲取矩陣數值" << std::endl;
for (int r = 0; r < n.rows; r++)
{for (int c = 0; c < n.cols; c++){std::cout << n.at<int>(r, c) << ",";//用at時注意只能對n處理,m未規定數字,且rc不要過界否則報內存錯誤std::cout << n.at<int>(Point(c, r)) << ",";//用Point時c在前r在后}}
std::cout << "\n"<<"利用指針獲取矩陣數值" << std::endl;
for (int r = 0; r < n.rows; r++)
{//獲取矩陣n第r行首地址const int* ptr = n.ptr<int>(r);for (int c = 0; c < n.cols; c++){std::cout << ptr[c] << "\t";}std::cout << std::endl;
}
if (n.isContinuous())//這里不要忘記()獲取連續地址內存
{int *ptr = n.ptr<int>(0);std::cout << "\n" << "用iscontinue";for (int k = 0; k < n.rows*n.cols; k++){std::cout << ptr[k];}
}
//向量類
Vec<int, 3> vi(11, 22, 33);
Vec4f vf(1.2, 3.2, 1.1, 2.3);//即Vec<float,4>;Vec3d;Vec3b即Vec<uchar,3>
std::cout << "\n" << vi.rows;
std::cout << "\n" << vi.cols;
std::cout << "\n" << vi;
std::cout << "\n" << "訪問第i個元素" << vi[1];
std::cout << "\n" << vf;
std::cout << "\n" << "向量矩陣";
Mat mm = (Mat_<Vec3f>(2, 3) <<Vec3f(1, 11, 22), Vec3f(2, 12, 33), Vec3f(3, 13, 44), Vec3f(4, 14, 55),Vec3f(5, 15,66),Vec3f(6, 16, 77));
std::cout << mm;
std::cout << "\n" << "尺寸";
std::cout << mm.size();//注意加()
std::cout << "\n" << "打印向量矩陣每個值";
for (int r = 0; r < mm.rows; r++)
{for (int c = 0; c < mm.cols; c++){std::cout << mm.at<Vec3f>(r, c) << ",";}}
std::cout << "\n" << "采用指針";
for (int r = 0; r < mm.rows; r++)
{Vec3f* ptr = mm.ptr<Vec3f>(r);//第r行的第一個元素for (int c = 0; c < mm.cols; c++){std::cout << ptr[c] << ",";}
}
std::cout << "\n" << "采用成員變量data/step";
for (int r = 0; r < mm.rows; r++)
{for (int c = 0; c < mm.cols; c++){Vec3f *ptr = (Vec3f*)(mm.data + r*mm.step[0] + c*mm.step[1]);std::cout << *ptr;std::cout << mm.step[0];//第0維是線 3*4*3=36std::cout << mm.step[1];//每一維的大小:第1維是點 float四個字節,最低維(點)3(通道)*4(字節)=12}
}system("pause");
return 0;
}
TIPS1 Mat屬性里面的step/size的用法
for (int r = 0; r < mm.rows; r++){for (int c = 0; c < mm.cols; c++){Vec3f *ptr = (Vec3f*)(mm.data + r*mm.step[0] + c*mm.step[1]);std::cout << *ptr;std::cout << mm.step[0];//第0維是線 3*4*3=36std::cout << mm.step[1];//每一維的大小:第1維是點 float四個字節,最低維(點)3(通道)*4(字節)=12}}也就是說,這個數組內存區是連在一起的,首先先從data(首數值地址)開始,可以看出data地址是0,然后每遍歷一個Vec3f,地址往后走3*4(float是四字節的)個地址,然后遍歷完一個Vec3f就把*ptr地址更新
Mat matrix = (Mat_<int>(5, 5) << 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25);int r = 1;int c = 1;Mat mr = matrix.row(r);//輸出第r行Mat mc = matrix.col(c);//輸出第c列Mat r_range = matrix.rowRange(Range(2, 4));Mat c_range = matrix.colRange(Range(2, 4));cout << "\n"<< mr;cout << "\n"<< mc;cout << "\n" << r_range;cout << "\n" << c_range;
**改變矩陣數值**
r_range.at<int>(0,0)=10000;//改變r_range第0行第0列的值
//注意此時matrix第0行第0列的值也變了
使用成員函數clone和copyTo
先
Mat r_range = matrix.rowRange(2,4).clone();
或者
Mat r_range;
matrix.rowRange(2,4).copyTo(r_range)
這兩種方式都可以改變r_range值的同時不改變matrix
使用Rect類
#include "stdafx.h"
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
using namespace cv;
using namespace std;
int main()
{Mat img = imread("D:\\opencvfile\\ex2c++\\1.jpg", CV_LOAD_IMAGE_COLOR);if (img.empty())return -1;string winname = "原圖";namedWindow(winname, WINDOW_AUTOSIZE);imshow(winname, img);cvWaitKey(0);//一定要加這句不然圖片緩沖不出來system("pause");
}
顯示圖片的操作
1 注意路徑:C++里一定是雙斜杠+雙引號
2 注意cvWaitKey(0)這句一定要加
gemm的用法 參考opencv手冊
ch4.6 限制對比度的自適應直方圖均衡化
原理:自適應直方圖均衡化首先將圖像劃分為不重疊的區域塊(tiles),然后對每一個塊分
別進行直方圖均衡化。顯然,在沒有噪聲影響的情況下,每一個小區域的灰度直方圖會
被限制在一個小的灰度級范圍內;但是如果有噪聲,每一個分割的區域塊執行直方圖均
衡化后,噪聲會被放大。為了避免出現噪聲這種情況,提出了“限制對比度”(Contrast
Limiting)[3],如果直方圖的bin超過了提前預設好的“限制對比度”,那么會被裁減,然
后將裁剪的部分均勻分布到其他的bin,這樣就重構了直方圖。如圖4-9所示,假設設
置“限制對比度”為40,第四個bin的值為45,該值大于40,然后將多出的45-40=5均勻分布
到每一個bin,重構后的直方圖如圖(b)所示,接下來利用重構后的直方圖進行均衡化操
作。
Python中 sys.argv[]的用法詳解
sys.argv[]說白了就是一個從程序外部獲取參數的橋梁,這個“外部”很關鍵,所以那些試圖從代碼來說明它作用的解釋一直沒看明白。因為我們從外部取得的參數可以是多個,所以獲得的是一個列表(list),也就是說sys.argv其實可以看作是一個列表,所以才能用[]提取其中的元素。其第一個元素是程序本身,隨后才依次是外部給予的參數。
https://blog.csdn.net/woailyoo0000/article/details/79310728
限制對比度的自適應直方圖均衡化(AHE),解決了全局直方圖均衡化(HE)處理后產生的失真和噪聲情況
import cv2
import numpy as np
import sys
if __name__=="__main__":src = cv2.imread("D:\pythonlearning\gamma\img3.jpg")src = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)clahe = cv2.createCLAHE(clipLimit=1.0,tileGridSize=(8,8))dst = clahe.apply(src)cv2.imshow("src",src)cv2.imshow("clahe",dst)cv2.waitKey(0)cv2.destroyAllWindows()
OpenCV Error: Assertion failed (_src.type() == (((0) & ((1 << 3) - 1)) + (((1)-1) << 3)) || _src.type() == (((2) & ((1 << 3) - 1)) + (((1)-1) << 3))) in `anonymous-namespace'::CLAHE_Impl
這個錯誤解決方案:
convert each frame to grayscale or apply it on each channel
#convert to grayscale
gray_image = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
6 閾值分割
它是一種基于區域的、簡單的通過灰度值信息提取形狀的技術,因其實現簡單、計算量小、性能穩定而成為圖像分割中最基本和應用最廣泛的分割技術。往往閾值分割后的輸出圖像只有兩種灰度值:255和0,所以閾值分割處理又常稱為圖像的二值化處理。閾值分割處理過程可以看作眼睛從背景中分離出前景的過程,閾值分割處理主要是根據灰度值信息提取前景,所以對前景物體與背景有較強對比度的圖像的分割特別有用。對對比度很弱的圖像進行閾值分割,需要先進行圖像的對比度增強,然后再進行閾值處理。下面介紹兩種常用的閾值分割技術:全局閾值分割和自適應局部閾值分割。
全局閾值,整幅圖像采用同一個數作為閾值。這種方法并不適應與所有情況,尤其是當同一幅圖像上的不同部分的具有不同亮度時。這種情況下我們需要采用自適應閾值。此時的閾值是根據圖像上的每一個小區域計算與其對應的閾值。
因此在同一幅圖像上的不同區域采用的是不同的閾值,從而使我們能在亮度不同的情況下得到更好的結果。這種方法需要我們指定三個參數,返回值只有一個。
? Adaptive Method- 指定計算閾值的方法。
– cv2.ADPTIVE_THRESH_MEAN_C:閾值取自相鄰區域的平均值
– cv2.ADPTIVE_THRESH_GAUSSIAN_C:閾值取值相鄰區域的加權和,權重為一個高斯窗口
總結
以上是生活随笔為你收集整理的opencv算法精解 c++/python的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。