Reputation: 4993
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:
and this output image:
Upvotes: 8
Views: 19166
Reputation: 3550
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:
output images:
Upvotes: 4
Reputation: 5708
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)
Upvotes: 17