19 Ocak 2018 Cuma

OpenCV

Giriş
Aşağıda notlarım var.
Image Processing görüntü işleme demek, yani resimden resim üretme gibi düşünülebilir. Görüntü işlemede temel iki yöntem var. İlki matris şeklinde resmi işleme, diğeri ise resmi sinyal gibi işleme.

Orthorectification - Orto Rektifikasyon
Uydu görüntülerinin işlenmeden önce hassas bir şekilde koordinatlandırılabilmesi ve topoğrafyaya göre geometrik düzeltmesinin yapılması anlamına gelir

Görüntü İşleme Yöntemleri
Görüntü filtreleme, gürültü giderme, görüntü birleştirme.

OpenCV altta gereken yerlerde Cuda kullanır.

Line İşlemleri
convexHull metodu
İmzası şöyle. Convex Hull belli bir nokta setinin tamamını içeren polygon'dur.
void
convexHull(InputArray points,
           OutputArray hull,
           bool clockwise=false,
           bool returnPoints=true);
convexhull + polyline metodu ile contour çizilebilir.

Örnek
Şöyle yaparız.
using (var src = new Mat(filePath))
using (var gray = new Mat())
{
  using (var bw = src.CvtColor(ColorConversionCodes.BGR2GRAY)) // convert to grayscale
  {
    // invert b&w (specific to your white on black image)
    Cv2.BitwiseNot(bw, gray);
  }

  // find all contours
  var contours = gray.FindContoursAsArray(RetrievalModes.List,
    ContourApproximationModes.ApproxSimple);
  using (var dst = src.Clone())
  {
    foreach (var contour in contours)
    {
      // filter small contours by their area
      var area = Cv2.ContourArea(contour);
      if (area < 15 * 15) // a rect of 15x15, or whatever you see fit
        continue;

      // also filter the whole image contour (by 1% close to the real area)
      if (Math.Abs((area - (src.Width * src.Height)) / area) < 0.01f)
        continue;

      var hull = Cv2.ConvexHull(contour);
      Cv2.Polylines(dst, new[] { hull }, true, Scalar.Red, 2);
    }

    using (new Window("src image", src))
    using (new Window("dst image", dst))
    {
      Cv2.WaitKey();
    }
  }
}
polylines metodu
İmzası şöyle.
void cv::polylines  (
    InputOutputArray     img,
    InputArrayOfArrays   pts,
    bool                 isClosed,
    const Scalar &       color,
    int                  thickness = 1,
    int                  lineType = LINE_8,
    int                  shift = 0 
)
LineIterator
İki nokta arasındaki pikselleri dolaşmak için şöyle yaparız.
// grabs pixels along the line (pt1, pt2)
// from 8-bit 3-channel image to the buffer
LineIterator it(img, pt1, pt2);
vector<Vec3b> buf(it.count);

// iterate through the line
for(int i = 0; i < it.count; i++, ++it)
    buf[i] = *(const Vec3b)*it;


Resim Yükleme
cvLoadImage
Bu metod ile resimleri yüklemek mümkün. Örnek: Bu metodu sadece C kullanırken kullanmak lazım. C++ ile cv::Mat sınıfını kullanmak gerek.
IplImage* src = cvLoadImage(argv[1],0);

Resim İşleme Metodları
absdiff
İki resim arasındaki farkı verir.
cv::Mat first,second,result;
//first= some image
//second =other image
cv::absdiff(first,second,result);
İki resim de aynı tipte olmalıdır, örneğin CV_8UC1 gibi yoksa şöyle bir hata alırız.
OpenCV Error: Bad argument (when the input arrays in add/subtract/multiply/divide 
functions have different types, the output array type must be explicitly 
specified)
in arithm_op, file /opt/opencv/modules/core/src/arithm.cpp, line 683.
terminate called after throwing an instance of 'cv::Exception'

calculate optical flow
Bir resimdeki 4 noktanın devamının bir başka resimde nerede olacağını verir. Şöyle yaparız.
std::vector<cv::Point> prev{p1,p2,p3,p4};
std::vector<cv::Point> next;
cv::calcOpticalFlowPyrLK(
  mat_prev, mat_next, 
  prev,
  next, 
  status, 
  err  
);
circle metodu
Open CV Drawing Functions yazısına taşıdım.

copyMakeBorder metodu
Resmin kenarları olsun istersek şöyle yaparız.
int borderSize = 2;

cv::copyMakeBorder(input, output, borderSize, borderSize,
               borderSize, borderSize, BORDER_REPLICATE);
createTrackBar metodu
Global değişkenler kullanarak şöyle yaparız.
int thresh = 100;
int max_thresh = 255;
/// Function header
void thresh_callback(int, void* );

createTrackbar( "Canny thresh:", "Source", &thresh, max_thresh, thresh_callback );
thresh_callback( 0, 0 );

/** @function thresh_callback */
void thresh_callback(int, void* )
{
  ...
}
fillConvexPoly metodu
Resmin belirtilen alanini belirtilen renk ile doldurur. Şöyle yaparız.
import cv2
import numpy
img = cv2.imread("zebra.jpg")
img = cv2.cvtColor(img, cv2.COLOR_BGR2BGRA) #convert to 4-channel image
triangle = numpy.array([[300, 0], [399, 0], [399, 100]])
color = [255, 255, 255, 0] #white with zero alpha
cv2.fillConvexPoly(img, triangle, color)
cv2.imwrite("with_triangle.png", img) #save to PNG for transparency support

inRange metodu
OpenCV Threshold Metodları yazısına taşıdım.

mixChannels metodu
Şöyle yaparız.
Mat blurred = ...;

Mat gray0(blurred.size(), CV_8U), gray;


// find squares in every color plane of the image
for (int c = 0; c < 3; c++)
{
  int ch[] = {c, 0};
  mixChannels(&blurred, 1, &gray0, 1, ch, 1);
  ...
}
normalize
Mat sınıfındaki her değer 0-1 arasında olacak şekilde ayarlanır.
cv::Mat data = (cv::Mat_<float>(2, 4) << 1.f, 2.f, 3.f, 4.f,
                                         5.f, 6.f, 7.f, 8.f);
cv::Mat res;
cv::normalize(data, res, 1, 0, cv::NORM_INF); // scale to [0,1]
std::cout << res;
filter2D
Şöyle yaparız.
filter2D(src_image, dst_image, src_image.depth(), mat);

putText metodu
Şöyle yaparız.
putText(frame, "...", Point(25, 40), 2, 1, CV_RGB(255, 255, 0), 1, 8, false);
pryUp()
Bu metod ile resimlere zoomlamak mümkün.

resize metodu
OpenCV Geometric Image Transformations yazısına taşıdım.

subtract
Örnekte aynı boyuttaki iki resim birbirlerinden çıkarılıyor. Eğer tıpatıp aynı iki resmi birbirinden çıkarırsak boş bir resim elde ederiz
#include <cv.h>
#include <highgui.h>

using namespace cv;

Mat im = imread("cameraman.tif");
Mat im2 = imread("lena.tif");

Mat diff_im = im - im2;
Canny
Canny Edge Detection yazısına taşıdım.

cvCvtColor metodu - C 
OpenCv Miscellaneous Image Transformations yazısına taşıdım.

 cvtColor metodu - C++
OpenCv Miscellaneous Image Transformations yazısına taşıdım.

drawCountours metodu
OpenCV Contour yazısına taşıdım.

findCountours metodu - input + output + mode + method
OpenCV Contour yazısına taşıdım.

findCountours metodu - input + output + hierarchy + mode + method
OpenCV Contour yazısına taşıdım.

saturate_cast metodu
Şöyle yaparız.
uchar u1 = 257;  // u1 = 1
uchar u2 = saturate_cast<uchar>(257); // u2 = 255
split metodu
Veriyi BGR olarak ayırır. Şöyle yaparız.
Mat src = ...
vector<Mat> rgb;

cv::split (src, rgb);
rgb [2] //red
rgb [1] //green
rgb [0] //blue
Resim
Resim Yükleme ve Yazma
OpenCV Resim Yükleme ve Yazma yazısına taşıdım.

CvMat Yapısı
CvMat yapısı yazısına taşıdım.

cvGet2D ve cvSet2D
Bir matris yaratıp, satır/sütun değerlerini alıp değiştirmek mümkün. Örnek:

Mat sınıfı
Mat Sınıfı yazısına taşıdım.

Video Capture
OpenCV Video Yakalama yazısına taşıdım.

Video Motion Detection
Konuyla ilgili bir kaç not almak istedim. Video frame'lerini kullanarak hareketi tespit etmek için aşağıdaki yöntem kullanılabilir. İki frame karşılaştırılarak arka plan (background) bulunur. Arka plan hep sabit kaldığı için resimden çıkartılır. Örneğin siyah yapılır. Kalan pixeller de beyaz yapılır.
Beyaz pixellere bakara hareket eden şekil tanınmaya çalışılır. Şekil insanı andırıyorsa hırsız alarmı verilebilir.


Resimde Gürültü (Image Noise)
OpenCV Image Smoothing yazısına taşıdım.

Inpainting
Bozuk resmin onarılması demektir.

CascadeClassifier Sınıfı
CascadeClassifier Sınıfı yazısına taşıdım.

ml
Konuyu tam anlamadım. Kullanmak için şu dosyalalar gerekir.
#include "opencv2/core/core.hpp"
#include "opencv2/ml/ml.hpp"
Vectöre şöyle çeviririz.
std::vector<Node> nodeList(forest->getNodes().size());
CvSVM Sınıfı
train metodu
Şöyle yaparız.
Mat training_mat = ...;
Mat labels = ...;

CvSVMParams params;
params.svm_type = CvSVM::C_SVC;
params.kernel_type = CvSVM::POLY;
params.gamma = 3;
params.degree =3;
CvSVM svm;
svm.train(training_mat, labels, Mat(), Mat(), params);
svm.save("svm_filename");






1 yorum: