合計 昨日 今日

OpenCVを使い画素数を調べる

[このトピックは解決済みです]

フォーラムルール
フォーラムルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
Name: aaaa
[URL]
ぴよぴよ(680 ポイント)
Date: 2017年10月09日(月) 15:55
No: 1
(OFFLINE)

 OpenCVを使い画素数を調べる

こんにちは。
私は今OpenCVを使い「赤と青どちらの画素数が多いかを調べたい」と考えています

しかし、私は大変初心者なので、調べても全くわかりませんでした。。。
cv::countNonZero という関数を使うのではないかということしかわかりませんでした(使い方もわかりませんでした。。。)

全く手付かずの状態で投げっぱなしの質問になってしまいますが、画素数の調べ方を教えていただけたら幸いです。

よろしくお願いします。

Name: aaaa
[URL]
ぴよぴよ(680 ポイント)
Date: 2017年10月09日(月) 16:08
No: 2
(OFFLINE)

 Re: OpenCVを使い画素数を調べる

訂正失礼いたします。

CountNonZeroの使い方がわからないというのは文字通りの意味と、この関数の意味もわからないということです。。。(リファレンスは一応読みました)

使い方に関しては

コード[C++]: 全て選択
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
using namespace cv;
 
int main(int argc, const char *argv[])
{
    /*genga*/
    Mat src_image = imread("red.jpg");
    namedWindow("genga");
    imshow("genga", src_image);
   
    int width = src_image.cols;
    int height = src_image.rows;
   
    int count =0;
    count +=CountNonZero(src_image);
    printf("%d\n",count);


というプログラムをつくったのですが、
‘src_img’ was not declared in this scope
count +=CountNonZero(src_image);

とでてしまいました。
src_image ではないものを入れるの必要があるのでしょうか

Name: asd
[URL]
比類なきプログラマー(70,671 ポイント)
Date: 2017年10月09日(月) 22:41
No: 3
(OFFLINE)

 Re: OpenCVを使い画素数を調べる

aaaa さんが書きました:訂正失礼いたします。

CountNonZeroの使い方がわからないというのは文字通りの意味と、この関数の意味もわからないということです。。。(リファレンスは一応読みました)


リファレンスによると、引数に渡されたシングルチャンネルの配列から0でない画素数をカウントし返すとありますので、
例えばHSVチャンネルのHだけの画素数をカウントしたり、Sだけの画素数をカウントしたりといった使い方になるかと思います。

(参考)
http://opencv.jp/opencv-2svn/c/operatio ... l#index-23

もし以下の以前のトピックで上がっていた「赤の画素、青の画素をカウントする」目的では利用は難しいと思います。
(H、Sそれぞれの値が特定の範囲のものを赤または青としてカウントする必要があるため、Hチャンネルだけの画素をカウントしてもダメですし、Sチャンネルだけの画素をカウントしてもダメだと思いますので)

(以前のトピック)
viewtopic.php?f=3&t=19609

それはさておき提示されたプログラムにも言及しておきますね。

aaaa さんが書きました:というプログラムをつくったのですが、
‘src_img’ was not declared in this scope
count +=CountNonZero(src_image);

とでてしまいました。
src_image ではないものを入れるの必要があるのでしょうか


出ているエラーはその1つだけでしょうか?
閉じ括弧が足りないことと、プログラム中に存在していないsrc_imgという変数名でエラーが出ているので、
お手元のプログラムをよく確認し、

・src_imageのつもりでsrc_imgと書いている部分がないか
・閉じ括弧の対応は正しいか

を確認してみてください。

ただ、それを解決しても別のエラーが出るかと思いますので、いずれかのチャンネルだけを渡すようにすればカウントはしてくれるとは思います
(src_imageはシングルチャンネルの配列ではないためsplit関数なりで分解する必要がある)

これで動作するとよいのですが、分からない箇所があればまた聞いてください(*´ヮ`)
Advanced Supporting Developer
無理やりこじつけ(ぉ

Name: aaaa
[URL]
ぴよぴよ(680 ポイント)
Date: 2017年10月10日(火) 14:26
No: 4
(OFFLINE)

 Re: OpenCVを使い画素数を調べる

asd様
返信有り難うございます。

詳しい説明ありがとうございます。
CountNonZeroは一つのものしか数えられないのですね。。。

以前のトピックでおっしゃられていた、「その場合だとフラグ方式よりも、赤と青の各成分量(ピクセル数)をカウントするようにした方がよいのかもです。」とのことですが、これはどのような手法を使えばよいか教えていただくことはできないでしょうか。。。

よろしくお願いします

Name: aaaa
[URL]
ぴよぴよ(680 ポイント)
Date: 2017年10月10日(火) 14:39
No: 5
(OFFLINE)

 Re: OpenCVを使い画素数を調べる

毎度のことながら度々申し訳ございません

何か関数を使わなければいけないのかと思いましたが、自分なりにプログラムを作ってみたのでこれが考え方があってるのか教えていただけたら嬉しいです。

コード[C++]: 全て選択
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/*
 * hsv change
 */
 
 
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/core/core.hpp"
 
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <iostream>
#include <fstream>
#include <sstream>
 
using namespace cv;
 
int main(int argc, const char *argv[])
{
    /*genga*/
    Mat src_image = imread("red.jpg");
    namedWindow("genga");
    imshow("genga", src_image);
   
    int width = src_image.cols;
    int height = src_image.rows;
   
    /*
    int count =0;
    count +=CountNonZero(src_image);
    printf("%d\n",count);
    */
    /*HSV*/
    Mat hsv_image;
    cvtColor(src_image, hsv_image, CV_BGR2HSV);
   
    uchar hue, sat, val;
    Mat red_image = Mat(Size(width, height),CV_8UC1);
    Mat blue_image = Mat(Size(width, height),CV_8UC1);
   
    int flag_red = 0;
    int flag_blue = 0;
   
    /*ピクセル*/
    int pixel_red = 0;
    int pixel_blue = 0;
   
    for(int y=0; y<height; y++)
        for(int x=0; x<width; x++)
        {
            /*H,S,V*/
            hue = hsv_image.at<Vec3b>(y, x)[0];
            sat = hsv_image.at<Vec3b>(y, x)[1];
            val = hsv_image.at<Vec3b>(y, x)[2];
           
            /*red_detect*/
            if((hue<10 || hue>170) && sat>45){
                red_image.at<uchar>(y, x) = 0;
                flag_red = 1;
                pixel_red ++;
               
            }  
               
            else
                red_image.at<uchar>(y, x) = 255;
               
       
               
            /*blue_detect*/
            if((hue>75 && hue<90) && sat>60){
                blue_image.at<uchar>(y, x) = 0;
                flag_blue = 1;
                pixel_blue ++;
            }
           
            else
                blue_image.at<uchar>(y, x) = 255;
               
    }
   
    namedWindow("red_detect");
    imshow("red_detect", red_image);
   
    namedWindow("blue_detect");
    imshow("blue_detect", blue_image);
/*
    if(flag_red=1){
    printf("red\n");
    }
*/ 
    if(flag_blue=1){
    printf("blue\n");
    }
   
    printf("%d\n",pixel_red);
    printf("%d\n",pixel_blue);
   
    waitKey(0);
    destroyAllWindows();
    return 0;
}



赤、青それぞれのif の中でカウントをすればいいのではないかと思いこうしてみました。
一応横280、縦200の赤色の画像を読み込んだら、赤56000、青0と出ました。

よろしくお願いします。

Name: asd
[URL]
比類なきプログラマー(70,671 ポイント)
Date: 2017年10月10日(火) 18:56
No: 6
(OFFLINE)

 Re: OpenCVを使い画素数を調べる

aaaa さんが書きました:毎度のことながら度々申し訳ございません

何か関数を使わなければいけないのかと思いましたが、自分なりにプログラムを作ってみたのでこれが考え方があってるのか教えていただけたら嬉しいです。



いえいえ、少しずつ進んでいる様子が見られて、私も回答しがいがあると思っていますのでお気になさらず。
提示されているプログラムで考え方は正しいかと思います。
(CountNonZero利用で難しいとなった場合には提示されているプログラムと同じ考え方を回答するつもりでした)

赤色の画像でのピクセル数と画像全体のピクセル数も一致しているとのことで、数え間違いや重複カウントもなく
正しく動いていそうですね。

次はいろいろな信号機画像で試してみてうまく判定できるかを確認する段階でしょうか。
正しく判定できない画像が見つかった場合にはどのように改善するかを検討することになろうかと思いますが、
引き続き頑張ってください(*´ヮ`)
Advanced Supporting Developer
無理やりこじつけ(ぉ

Name: 沖 滉均
[URL]
熟練のプログラマー(51,181 ポイント)
Date: 2017年10月11日(水) 09:40
No: 7
(OFFLINE)

 Re: OpenCVを使い画素数を調べる

Offtopic :
本題とはそれてるけど確認に支障でそうなので念のため
コード[C++]: 全て選択
1
2
3
4
5
6
7
8
/*
    if(flag_red=1){
    printf("red\n");
    }
*/  
    if(flag_blue=1){
    printf("blue\n");
    }
インデントはともかく、if文の中がフラグの判定ではなく代入になっているのでご注意を…
There is no royal road to learning.
[code]タグで指定できる言語
沖の雑記帳

Name: asd
[URL]
比類なきプログラマー(70,671 ポイント)
Date: 2017年10月11日(水) 10:06
No: 8
(OFFLINE)

 Re: OpenCVを使い画素数を調べる

Offtopic :
沖 滉均 さんが書きました:インデントはともかく、if文の中がフラグの判定ではなく代入になっているのでご注意を…


ご指摘ありがとうございます。
確かに代入になってしまっているので正しく判定されない事象につながってしまいますね。
見返してみると前のトピックから同じ記述だったのでその時から見落としていたようです…
Advanced Supporting Developer
無理やりこじつけ(ぉ

Name: aaaa
[URL]
ぴよぴよ(680 ポイント)
Date: 2017年10月11日(水) 13:38
No: 9
(OFFLINE)

 Re: OpenCVを使い画素数を調べる

[解決!]

asd様、 沖 滉均様、返信ありがとうございます。

asd様
おかげさまで、手元にある画像では無事に判別することができました。
本当にありがとうございます。

>正しく判定できない画像が見つかった場合にはどのように改善するかを検討することになろうかと思いますが、
引き続き頑張ってください(*´ヮ`)

ありがとうございます。またお助けをお願いすることがあるかもしれませんがその時はよろしくお願いします。

沖 滉均様
以前のプログラムで正しく判別できなかった理由が代入になっていたということがわかりました。
ご指摘ありがとうございます。

皆様感謝いたします。

Name: asd
[URL]
比類なきプログラマー(70,671 ポイント)
Date: 2017年10月12日(木) 00:09
No: 10
(OFFLINE)

 Re: OpenCVを使い画素数を調べる

[解決!]

aaaa さんが書きました:asd様
おかげさまで、手元にある画像では無事に判別することができました。
本当にありがとうございます。


無事に解決したようでなによりです(*´ヮ`)

aaaa さんが書きました:ありがとうございます。またお助けをお願いすることがあるかもしれませんがその時はよろしくお願いします。


タイミングによっては私が回答できる保証はないのですが、
またトピックをお見かけした際には助言ができたらなと思っています。
頑張ってください!
Advanced Supporting Developer
無理やりこじつけ(ぉ


Return to C言語何でも質問掲示板

オンラインデータ

このフォーラムを閲覧中のユーザー: なし & ゲスト[12人]