Hello again!
After a long hiatus I’m back with an update. Recently I’ve been upgrading the Structure-from-Motion Toy Library (https://github.com/royshil/SfM-Toy-Library/) to OpenCV 3.x from OpenCV 2.4.x.
Category: opencv
I tried to set the capture format on a webcam from OpenCV’s cv2.VideoCapture and ran into a problem: it’s using the wrong IOCTL command.
So I used python-v4l2capture to get images from the device, which allows more control.
Here is the gist:
Enjoy!
Roy
I wasn’t able to find online a complete example on how to persist OpenCV matrices in Python (so really NumPy arrays) to YAML like what cv::FileStorage will give you.
So here’s a short snippet:
import numpy as np import yaml # A yaml constructor is for loading from a yaml node. # This is taken from: http://stackoverflow.com/a/15942429 def opencv_matrix_constructor(loader, node): mapping = loader.construct_mapping(node, deep=True) mat = np.array(mapping["data"]) mat.resize(mapping["rows"], mapping["cols"]) return mat yaml.add_constructor(u"tag:yaml.org,2002:opencv-matrix", opencv_matrix_constructor) # A yaml representer is for dumping structs into a yaml node. # So for an opencv_matrix type (to be compatible with c++'s FileStorage) we save the rows, cols, type and flattened-data def opencv_matrix_representer(dumper, mat): mapping = {'rows': mat.shape[0], 'cols': mat.shape[1], 'dt': 'd', 'data': mat.reshape(-1).tolist()} return dumper.represent_mapping(u"tag:yaml.org,2002:opencv-matrix", mapping) yaml.add_representer(np.ndarray, opencv_matrix_representer) #example with open('output.yaml', 'w') as f: f.write("%YAML:1.0") yaml.dump({"a matrix": np.zeros((10,10)), "another_one": np.zeros((2,4))}, f) # a matrix: !!opencv-matrix # cols: 10 # data: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, # 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, # 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, # 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, # 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, # 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, # 0.0, 0.0, 0.0, 0.0, 0.0] # dt: d # rows: 10 # another_one: !!opencv-matrix # cols: 4 # data: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] # dt: d # rows: 2 with open('output.yaml', 'r') as f: print yaml.load(f) # {'a matrix': array([[ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], # [ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], # [ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], # [ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], # [ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], # [ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], # [ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], # [ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], # [ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], # [ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]]), 'another_one': array([[ 0., 0., 0., 0.], # [ 0., 0., 0., 0.]])}
There you go
Using Poppler, of course!
Poppler is a very useful tool for handling PDF, so I’ve discovered lately. Having tried both muPDF and ImageMagick’s Magick++ and failed, Poppler stepped up to the challenge and paid off.
So here’s a small example of how work the API (with OpenCV, naturally):
#include <iostream> #include <fstream> #include <sstream> #include <opencv2/opencv.hpp> #include <poppler-document.h> #include <poppler-page.h> #include <poppler-page-renderer.h> #include <poppler-image.h> using namespace cv; using namespace std; using namespace poppler; Mat readPDFtoCV(const string& filename,int DPI) { document* mypdf = document::load_from_file(filename); if(mypdf == NULL) { cerr << "couldn't read pdf\n"; return Mat(); } cout << "pdf has " << mypdf->pages() << " pages\n"; page* mypage = mypdf->create_page(0); page_renderer renderer; renderer.set_render_hint(page_renderer::text_antialiasing); image myimage = renderer.render_page(mypage,DPI,DPI); cout << "created image of " << myimage.width() << "x"<< myimage.height() << "\n"; Mat cvimg; if(myimage.format() == image::format_rgb24) { Mat(myimage.height(),myimage.width(),CV_8UC3,myimage.data()).copyTo(cvimg); } else if(myimage.format() == image::format_argb32) { Mat(myimage.height(),myimage.width(),CV_8UC4,myimage.data()).copyTo(cvimg); } else { cerr << "PDF format no good\n"; return Mat(); } return cvimg; }
All you have to do is give it the DPI (say you want to render in 100 DPI) and a filename.
Keep in mind it only renders the first page, but getting the other pages is just as easy.
That’s it, enjoy!
Roy.
You already know I love libQGLViewer. So here a snippet on how to do AR in a QGLViewer widget. It only requires a couple of tweaks/overloads to the plain vanilla widget setup (using the matrices properly, disable the mouse binding) and it works.
The major problems I recognize with getting a working AR from OpenCV’s intrinsic and extrinsic camera parameters are their translation to OpenGL. I saw a whole lot of solutions online, and I contributed from my own experience a while back, so I want to reiterate here again in the context of libQGLViewer, with a couple extra tips.
Just sharing a simple recipe for a video stabilizer in OpenCV based on goodFeaturesToTrack() and calcOpticalFlowPyrLK().
Well… it’s a bit more than 20 lines, but it is short. And it doesn’t work for every kind of video (although the results are funny anyway! :).
So lately I’m into Optical Music Recognition (OMR), and a central part of that is doing staff line removal. That is when you get rid of the staff lines that obscure the musical symbols to make recognition much easier. There are a lot of ways to do it, but I’m going to share with you how I did it (fairly easily) with Hidden Markov Models (HMMs), which will also teach us a good lesson on this wonderfully useful approach.
OMR has been around for ages, and if you’re interested in learning about it [Fornes 2014] and [Rebelo 2012] are good summary articles.
The matter of Staff Line Removal has occupied dozens of researchers for as long as OMR exists; [Dalitz 2008] give a good overview. Basically the goal is to remove the staff lines that obscure the musical symbols, so they would be easier to recognize.
But, the staff lines are connected to the symbols, so simply removing them will cut up the symbols and make them hardly recognizable.
So let’s see how we could do this with HMMs.
I came across an extremely simple color balancing algorithm here. And I thought I’ll quickly transcode it to OpenCV.
Here’s the gist:
Simple NURBS renderer [w/ code]
Don’t you just love scouring the web for a piece of simple code, come up short and then just write it yourself? Well that was the case with NURBS for me. These simple curvy lines, why doesn’t anyone just dish out a straightforward implementation of them? Well, now you have it. I wrote a simple renderer that reads a DXF file with NURBS (from Rhino3D) using DXFLIB, although the DXF file format is super easy to parse, and renders them to an image with OpenCV.