Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenCV: How can I find the color inside a contour/polygon?

Tags:

python

opencv

Here is what I have

im = cv2.imread('luffy.jpg')
gray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(gray,127,255,0)

contours,h = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

for cnt in contours:

    // return color inside of the contour here
    mask = np.zeros(cnt.shape[:2],np.uint8)
    mean = cv2.mean(cant,mask)   // I think this is promising but so far it returns arrays with just zeros. I think its because I used np.zeros above to find the mask....
    moment = cv2.moments(cnt)   //maybe this will help?

I can find no such openCV function built in. I assume perhaps you can do it with the moments? How can I achieve this??

EDIT: with the proposed solution given by Zaw Lin I have this input image:

enter image description here

and this output image:

enter image description here

like image 313
BigBoy1337 Avatar asked Jan 23 '16 22:01

BigBoy1337


People also ask

Can OpenCV detect colors?

OpenCV has some built-in functions to perform Color detection and Segmentation operations. So what are Color Detection and Segmentation Techniques in Image Processing? Color detection is a technique of detecting any color in a given range of HSV (hue saturation value) color space.

How do you know what color to use for contouring?

Use the findContours() function to detect the contours in the image. Draw Contours on the Original RGB Image.

How do you match contours in OpenCV?

OpenCV comes with a function cv. matchShapes() which enables us to compare two shapes, or two contours and returns a metric showing the similarity. The lower the result, the better match it is.


2 Answers

This gets the average color inside each contour and draws contours with that color to final image.

import cv2
import numpy as np
im = cv2.imread('/home/zawlin/test.png')

gray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
contours,h = cv2.findContours(gray,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

final = np.zeros(im.shape,np.uint8)
mask = np.zeros(gray.shape,np.uint8)

for i in xrange(0,len(contours)):
    mask[...]=0
    cv2.drawContours(mask,contours,i,255,-1)
    cv2.drawContours(final,contours,i,cv2.mean(im,mask),-1)

cv2.imshow('im',im)
cv2.imshow('final',final)
cv2.waitKey(0)
like image 113
Zaw Lin Avatar answered Sep 21 '22 06:09

Zaw Lin


i think function mean with a mask image is the only way to get color inside a contour but sorry i can't show it by Python code.

you can get bounding box of a contour by boundingRect and use it to get image ROI from source image and binarized image for masking ( be aware of cloning binarized image because findcontour destroys it)

maybe a sample c++ will be useful ( sorry for my poor english.)

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>

using namespace cv;
using namespace std;

int main( int, char** argv )
{
  /// Load source image
  Mat src = imread(argv[1]);
  if (src.empty())
  {
    cerr << "No image supplied ..." << endl;
    return -1;
  }

  /// Convert image to gray
  Mat src_gray;
  cvtColor( src, src_gray, COLOR_BGR2GRAY );
  threshold( src_gray, src_gray, 50, 255, THRESH_BINARY );
  imshow( "src_gray", src_gray );
  /// Find contours
  vector<vector<Point> > contours;
  findContours( src_gray.clone(), contours, RETR_TREE, CHAIN_APPROX_SIMPLE );

  Mat resImage0 = src.clone();
  Mat resImage1 = src.clone();
  /// Draw contours
  for( size_t i = 0; i< contours.size(); i++ )
     {
       Scalar color = Scalar( 0, 0, 255 );
       Rect _boundingRect = boundingRect( contours[i] );
       Scalar mean_color0 = mean( src( _boundingRect ) );
       Scalar mean_color1 = mean( src( _boundingRect ), src_gray( _boundingRect ) );

       drawContours( resImage0, contours, (int)i, mean_color0, FILLED );
       drawContours( resImage1, contours, (int)i, mean_color1, FILLED );
     }

  /// Show in a window
  imshow( "src", src );
  imshow( "resImage0", resImage0 );
  imshow( "resImage1", resImage1 );
  waitKey(0);
  return(0);
}

input image:

enter image description here

output images:

enter image description here enter image description here

like image 35
sturkmen Avatar answered Sep 17 '22 06:09

sturkmen