Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Run Length Encoding (vertical) on an OpenCV uchar Mat
#include <opencv2/opencv.hpp>
using namespace cv;
/**
* Compute RLE.
* RLE is encoded in a vector of vectors of (run length, value).
*
* @param patch_ the 8UC1 image to work on
* @param whichWay by which dimension? rows = 0, columns != 0
*/
vector<vector<pair<int,int> > > CalculateRLE(const Mat& patch_, int whichWay = 0) {
assert(!patch_.empty() && patch_.size().area() > 0 && patch_.type() == CV_8UC1);
Mat patch = (whichWay != 0) ? patch_.t() : patch_; // in case we want to RLE rows
vector<vector<pair<int,int> > > RLE;
//Adapted from: http://rosettacode.org/wiki/Run-length_encoding#Java
for (int col = 0; col < patch.cols; ++col) {
vector<pair<int,int> > colRLE;
for (int it = 0; it < patch.rows; it++) {
int runLength = 1;
while (it+1 < patch.rows && patch.at<uchar>(it,col) == patch.at<uchar>(it+1,col)) {
runLength++;
it++;
}
colRLE.push_back(make_pair(runLength,(int)(patch.at<uchar>(it,col))));
}
RLE.push_back(colRLE);
}
return RLE;
}
//Simple usage example
int main() {
Mat patch = imread("patch.png");
if(patch.channels != 1) cvtColor(patch,patch,CV_BGR2GRAY);
vector<vector<pair<int,int> > > RLE = CalculateRLE(patch > 0);
//visualize the RLE and output to console
Mat patch_RLE(patch.size(),CV_8UC3,Scalar::all(0));
for (int rle_it = 0; rle_it < RLE.size(); ++rle_it) {
cout << rle_it << ": ";
int tmp_pos = 0;
for (int j = 0; j < RLE[rle_it].size(); ++j) {
cout << RLE[rle_it][j].first << " " << RLE[rle_it][j].second << ", ";
line(patch_RLE,
Point(rle_it,tmp_pos),
Point(rle_it,tmp_pos+RLE[rle_it][j].first),
Scalar(255,0,RLE[rle_it][j].second),1);
tmp_pos += RLE[rle_it][j].first;
}
cout << endl;
}
imshow("patch",patch);
imshow("RLE",patch_RLE);
waitKey();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.