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:
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.
Use the findContours() function to detect the contours in the image. Draw Contours on the Original RGB Image.
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.
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)
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:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With