opencv2.4.9
↓を書き換えています
using namespace cv;
void thinningIte(Mat& img, int pattern){
Mat del_marker = Mat::ones(img.size(), CV_8UC1);
int x, y;
for (y = 1; y < img.rows - 1; ++y) {
for (x = 1; x < img.cols - 1; ++x) {
int v9, v2, v3;
int v8, v1, v4;
int v7, v6, v5;
v1 = img.data[y * img.step + x * img.elemSize()];
v2 = img.data[(y - 1) * img.step + x * img.elemSize()];
v3 = img.data[(y - 1) * img.step + (x + 1) * img.elemSize()];
v4 = img.data[y * img.step + (x + 1) * img.elemSize()];
v5 = img.data[(y + 1) * img.step + (x + 1) * img.elemSize()];
v6 = img.data[(y + 1) * img.step + x * img.elemSize()];
v7 = img.data[(y + 1) * img.step + (x - 1) * img.elemSize()];
v8 = img.data[y * img.step + (x - 1) * img.elemSize()];
v9 = img.data[(y - 1) * img.step + (x - 1) * img.elemSize()];
int S = (v2 == 0 && v3 == 1) + (v3 == 0 && v4 == 1) +
(v4 == 0 && v5 == 1) + (v5 == 0 && v6 == 1) +
(v6 == 0 && v7 == 1) + (v7 == 0 && v8 == 1) +
(v8 == 0 && v9 == 1) + (v9 == 0 && v2 == 1);
int N = v2 + v3 + v4 + v5 + v6 + v7 + v8 + v9;
int m1 = 0, m2 = 0;
if (pattern == 0) m1 = (v2 * v4 * v6);
if (pattern == 1) m1 = (v2 * v4 * v8);
if (pattern == 0) m2 = (v4 * v6 * v8);
if (pattern == 1) m2 = (v2 * v6 * v8);
if (S == 1 && (N >= 2 && N <= 6) && m1 == 0 && m2 == 0)
del_marker.data[y * del_marker.step + x * del_marker.elemSize()] = 0;
}
}
img &= del_marker;
}
void thinning(const Mat& src, Mat& dst){
dst = src.clone();
dst /= 255; // 0は0 , 1以上は1に変換される
Mat prev = Mat::zeros(dst.size(), CV_8UC1);
Mat diff;
do {
thinningIte(dst, 0);
thinningIte(dst, 1);
absdiff(dst, prev, diff);
dst.copyTo(prev);
} while (countNonZero(diff) > 0);
dst *= 255;
}
int main(){
Mat img = imread("a.bmp");
Mat img2;
cvtColor(img, img2, CV_BGR2GRAY);
threshold(img2, img2, 10, 255, CV_THRESH_BINARY);
thinning(img2, img2);
imshow("src", img);
imshow("dst", img2);
waitKey();
return 0;
}
void thinningのdo while
をどう書き換えればいいのか教えてください
v1~v9の書き換えはあってるのでしょうか
void thinningIte(IplImage *Img_nichi, int pattern){
IplImage *Img_sai;
Img_sai = cvCreateImage(cvGetSize(Img_nichi), IPL_DEPTH_8U,1);
for (int y = 1; y<Img_nichi->width - 1; y++){
for (int x = 1; x<Img_nichi->width - 1; x++){
int v9, v2, v3;
int v8, v1, v4;
int v7, v6, v5;
v1 = *(uchar*)(Img_nichi->imageData + (x + 0) + (y + 0) * Img_nichi->widthStep);
v2 = *(uchar*)(Img_nichi->imageData + (x + 0) + (y - 1) * Img_nichi->widthStep);
v3 = *(uchar*)(Img_nichi->imageData + (x + 1) + (y - 1) * Img_nichi->widthStep);
v4 = *(uchar*)(Img_nichi->imageData + (x + 1) + (y + 0) * Img_nichi->widthStep);
v5 = *(uchar*)(Img_nichi->imageData + (x + 1) + (y + 1) * Img_nichi->widthStep);
v6 = *(uchar*)(Img_nichi->imageData + (x + 0) + (y + 1) * Img_nichi->widthStep);
v7 = *(uchar*)(Img_nichi->imageData + (x - 1) + (y + 1) * Img_nichi->widthStep);
v8 = *(uchar*)(Img_nichi->imageData + (x - 1) + (y + 0) * Img_nichi->widthStep);
v9 = *(uchar*)(Img_nichi->imageData + (x - 1) + (y - 1) * Img_nichi->widthStep);
int S = (v2 == 0 && v3 == 1) + (v3 == 0 && v4 == 1) +
(v4 == 0 && v5 == 1) + (v5 == 0 && v6 == 1) +
(v6 == 0 && v7 == 1) + (v7 == 0 && v8 == 1) +
(v8 == 0 && v9 == 1) + (v9 == 0 && v2 == 1);
int N = v2 + v3 + v4 + v5 + v6 + v7 + v8 + v9;
int m1 = 0, m2 = 0;
if (pattern == 0) m1 = (v2 * v4 * v6);
if (pattern == 1) m1 = (v2 * v4 * v8);
if (pattern == 0) m2 = (v4 * v6 * v8);
if (pattern == 1) m2 = (v2 * v6 * v8);
if (S == 1 && (N >= 2 && N <= 6) && m1 == 0 && m2 == 0)
*(uchar*)(Img_sai->imageData + x + y * Img_sai->widthStep) = 0;
}
}
//Img_nichi &= Img_sai;
}
void thinning(IplImage *Img_1,IplImage *Img_2){
Img_2 = cvCreateImage(cvGetSize(Img_1), IPL_DEPTH_8U, 3);
cvCopy(Img_1, Img_2);
do {
thinningIte(Img_2, 0);
thinningIte(Img_2, 1);
} while ();
}
int main(int argc, char* argv[]){
IplImage *Img_orig; //元画像
IplImage *Img_gray; //グレースケール
IplImage *Img_nichi; //2値
IplImage *Img_sai0;
IplImage *Img_sai1;
int W, H; //widthとheight
int x, y; //カウント
int sikichi = 1; //閾値
//画像の読み込み
Img_orig = cvLoadImage("a.jpg", 1);
W = Img_orig->width;//幅
H = Img_orig->height;//高さ
//画像リソースの確保
Img_gray = cvCreateImage(cvSize(W, H), IPL_DEPTH_8U, 1); //白黒
Img_nichi = cvCreateImage(cvSize(W, H), IPL_DEPTH_8U, 1); //白黒
Img_sai0 = cvCreateImage(cvSize(W, H), IPL_DEPTH_8U, 1); //白黒
Img_sai1 = cvCreateImage(cvSize(W, H), IPL_DEPTH_8U, 1); //白黒
//グレースケール化
for (y=0 ; y<H ; y++){
for (x=0 ; x<W ; x++){
*(Img_gray->imageData + x + y * W) =
(char)((0.114 * *(uchar*)(Img_orig->imageData + (3 * x) + y * Img_orig->widthStep)) +
(0.587 * *(uchar*)(Img_orig->imageData + (3 * x + 1) + y * Img_orig->widthStep)) +
(0.299 * *(uchar*)(Img_orig->imageData + (3 * x + 2) + y * Img_orig->widthStep)));
}
}
//2値化
for (y=0 ; y<H ; y++){
for (x=0 ; x<W ; x++){
if (*(Img_gray->imageData + x + y*Img_gray->width) > sikichi){ //閾値より大きければ
*(Img_nichi->imageData + x + y*Img_nichi->width) = 0; //白
*(Img_sai0->imageData + x + y*Img_sai0->width) = 0;
}
else{ //それ以外
*(Img_nichi->imageData + x + y*Img_nichi->width) = 255; //黒
*(Img_sai0->imageData + x + y*Img_sai0->width) = 1;
}
}
}
//細線化
thinning(Img_sai0, Img_sai1);
//0と1を0と255にする
for (y = 0; y<H; y++){
for (x = 0; x<W; x++){
if (*(Img_sai1->imageData + x + y*Img_sai1->width) > 0){
*(Img_sai1->imageData + x + y*Img_sai1->width) = 255;
}
}
}
//画像の表示
cvShowImage("元画像", Img_orig);
cvShowImage("グレースケール", Img_gray);
cvShowImage("2値", Img_nichi);
cvShowImage("2値", Img_sai1);
//画像の保存
cvSaveImage("No_5a.bmp", Img_gray);
cvSaveImage("No_5b.bmp", Img_nichi);
cvSaveImage("No_5c.bmp", Img_sai1);
//キー入力待機
cvWaitKey(0);
//ウィンドウの破棄
cvDestroyAllWindows();
//画像リソースの解放
cvReleaseImage(&Img_orig);
cvReleaseImage(&Img_gray);
cvReleaseImage(&Img_nichi);
cvReleaseImage(&Img_sai1);
return 0;
}
http://www.cellstat.net/thinning/