Ostatnio zmodyfikowano wczoraj o godz. 18:32
tBane Temat założony przez niniejszego użytkownika |
» 2025-10-13 19:54:19 Tylko rysować outline, po to żeby było widać jaki kształt się zaznacza.  |
|
DejaVu |
» 2025-10-13 23:12:02 Model lokalny LLM ogarnął to w drugim podejściu, a ChatGPT jest teoretycznie znacznie mocniejszy niż mały model lokalny: #include <SFML/Graphics.hpp> #include <vector> #include <iostream>
bool isPointInPolygon( const sf::Vector2f & point, const std::vector < sf::Vector2f > & polygon ) { bool inside = false; int j = polygon.size() - 1; for( int i = 0; i < polygon.size(); ++i ) { if((( polygon[ i ].y > point.y ) !=( polygon[ j ].y > point.y ) ) && ( point.x <( polygon[ j ].x - polygon[ i ].x ) *( point.y - polygon[ i ].y ) /( polygon[ j ].y - polygon[ i ].y ) + polygon[ i ].x ) ) { inside = !inside; } j = i; } return inside; }
sf::Image extractRegion( const sf::Texture & texture, const std::vector < sf::Vector2f > & polygon ) { sf::Vector2u size = texture.getSize(); sf::Image result; result.create( size.x, size.y, sf::Color::Transparent ); sf::Image textureImage = texture.copyToImage(); const sf::Uint8 * pixels = textureImage.getPixelsPtr(); for( unsigned int y = 0; y < size.y; ++y ) { for( unsigned int x = 0; x < size.x; ++x ) { sf::Vector2f pixelPos( x, y ); if( isPointInPolygon( pixelPos, polygon ) ) { size_t index =( y * size.x + x ) * 4; sf::Color color( pixels[ index ], pixels[ index + 1 ], pixels[ index + 2 ], pixels[ index + 3 ] ); result.setPixel( x, y, color ); } } } return result; }
int main() { sf::RenderWindow window( sf::VideoMode( 1200, 600 ), "SFML Lasso Selection" ); sf::Texture texture; if( !texture.loadFromFile( "D:/image.jpg" ) ) { std::cerr << "Error: Could not load image.jpg" << std::endl; return - 1; } sf::Sprite sprite; sprite.setTexture( texture ); sprite.setPosition( 10, 10 ); sf::Image selectedImage; sf::Texture selectedTexture; sf::Sprite selectedSprite; selectedSprite.setPosition( 650, 10 ); std::vector < sf::Vector2f > lassoPoints; bool isDrawing = false; while( window.isOpen() ) { sf::Event event; while( window.pollEvent( event ) ) { if( event.type == sf::Event::Closed ) { window.close(); } if( event.type == sf::Event::MouseButtonPressed ) { if( event.mouseButton.button == sf::Mouse::Left ) { lassoPoints.clear(); lassoPoints.push_back( sf::Vector2f( event.mouseButton.x, event.mouseButton.y ) ); isDrawing = true; } } if( event.type == sf::Event::MouseButtonReleased ) { if( event.mouseButton.button == sf::Mouse::Left ) { isDrawing = false; if( lassoPoints.size() > 2 ) { selectedImage = extractRegion( texture, lassoPoints ); selectedTexture.loadFromImage( selectedImage ); selectedSprite.setTexture( selectedTexture ); } } } if( event.type == sf::Event::MouseMoved && isDrawing ) { lassoPoints.push_back( sf::Vector2f( event.mouseMove.x, event.mouseMove.y ) ); } } window.clear(); window.draw( sprite ); if( isDrawing && lassoPoints.size() > 1 ) { sf::ConvexShape lassoLine; lassoLine.setPointCount( lassoPoints.size() ); for( size_t i = 0; i < lassoPoints.size(); ++i ) { lassoLine.setPoint( i, lassoPoints[ i ] ); } lassoLine.setFillColor( sf::Color( 0, 0, 0, 0 ) ); lassoLine.setOutlineColor( sf::Color::Yellow ); lassoLine.setOutlineThickness( 2 ); window.draw( lassoLine ); } if( selectedImage.getSize().x > 0 && selectedImage.getSize().y > 0 ) { window.draw( selectedSprite ); } window.display(); } return 0; }
|
|
DejaVu |
» 2025-10-13 23:18:27 Tu masz kolejną iterację, aby było pokazane 'jakie zaznaczenie' zrobiono: #include <SFML/Graphics.hpp> #include <vector> #include <iostream>
bool isPointInPolygon( const sf::Vector2f & point, const std::vector < sf::Vector2f > & polygon ) { bool inside = false; int j = polygon.size() - 1; for( int i = 0; i < polygon.size(); ++i ) { if((( polygon[ i ].y > point.y ) !=( polygon[ j ].y > point.y ) ) && ( point.x <( polygon[ j ].x - polygon[ i ].x ) *( point.y - polygon[ i ].y ) /( polygon[ j ].y - polygon[ i ].y ) + polygon[ i ].x ) ) { inside = !inside; } j = i; } return inside; }
sf::Image extractRegion( const sf::Texture & texture, const std::vector < sf::Vector2f > & polygon ) { sf::Vector2u size = texture.getSize(); sf::Image result; result.create( size.x, size.y, sf::Color::Transparent ); sf::Image textureImage = texture.copyToImage(); const sf::Uint8 * pixels = textureImage.getPixelsPtr(); for( unsigned int y = 0; y < size.y; ++y ) { for( unsigned int x = 0; x < size.x; ++x ) { sf::Vector2f pixelPos( x, y ); if( isPointInPolygon( pixelPos, polygon ) ) { size_t index =( y * size.x + x ) * 4; sf::Color color( pixels[ index ], pixels[ index + 1 ], pixels[ index + 2 ], pixels[ index + 3 ] ); result.setPixel( x, y, color ); } } } return result; }
int main() { sf::RenderWindow window( sf::VideoMode( 1200, 600 ), "SFML Lasso Selection" ); sf::Texture texture; if( !texture.loadFromFile( "D:/image.jpg" ) ) { std::cerr << "Error: Could not load image.jpg" << std::endl; return - 1; } sf::Sprite sprite; sprite.setTexture( texture ); sprite.setPosition( 10, 10 ); sf::Image selectedImage; sf::Texture selectedTexture; sf::Sprite selectedSprite; selectedSprite.setPosition( 650, 10 ); std::vector < sf::Vector2f > lassoPoints; std::vector < sf::Vector2f > lastLassoPoints; bool isDrawing = false; bool selectionDone = false; while( window.isOpen() ) { sf::Event event; while( window.pollEvent( event ) ) { if( event.type == sf::Event::Closed ) { window.close(); } if( event.type == sf::Event::MouseButtonPressed ) { if( event.mouseButton.button == sf::Mouse::Left ) { lassoPoints.clear(); lassoPoints.push_back( sf::Vector2f( event.mouseButton.x, event.mouseButton.y ) ); isDrawing = true; selectionDone = false; } } if( event.type == sf::Event::MouseButtonReleased ) { if( event.mouseButton.button == sf::Mouse::Left ) { isDrawing = false; if( lassoPoints.size() > 2 ) { lastLassoPoints = lassoPoints; selectedImage = extractRegion( texture, lassoPoints ); selectedTexture.loadFromImage( selectedImage ); selectedSprite.setTexture( selectedTexture ); selectionDone = true; } } } if( event.type == sf::Event::MouseMoved && isDrawing ) { lassoPoints.push_back( sf::Vector2f( event.mouseMove.x, event.mouseMove.y ) ); } } window.clear(); window.draw( sprite ); if( isDrawing && lassoPoints.size() > 1 ) { sf::ConvexShape lassoLine; lassoLine.setPointCount( lassoPoints.size() ); for( size_t i = 0; i < lassoPoints.size(); ++i ) { lassoLine.setPoint( i, lassoPoints[ i ] ); } lassoLine.setFillColor( sf::Color( 0, 0, 0, 0 ) ); lassoLine.setOutlineColor( sf::Color::Yellow ); lassoLine.setOutlineThickness( 2 ); window.draw( lassoLine ); } if( !lastLassoPoints.empty() ) { sf::ConvexShape lastLasso; lastLasso.setPointCount( lastLassoPoints.size() ); for( size_t i = 0; i < lastLassoPoints.size(); ++i ) { lastLasso.setPoint( i, lastLassoPoints[ i ] ); } lastLasso.setFillColor( sf::Color( 0, 0, 0, 50 ) ); lastLasso.setOutlineColor( sf::Color::Green ); lastLasso.setOutlineThickness( 3 ); window.draw( lastLasso ); } if( selectionDone && selectedImage.getSize().x > 0 && selectedImage.getSize().y > 0 ) { window.draw( selectedSprite ); } window.display(); } return 0; }
Innymi słowy: musisz nauczyć się dzielić problem na mniejsze dla LLM-ów i sklejać sobie to w coś większego. |
|
tBane Temat założony przez niniejszego użytkownika |
» 2025-10-13 23:31:17 Wrzuciłeś kod pod stary SFML. W nowym SFML 3.0.2 nie ma sf::Image::create ani sf::Uint8 oraz nie można tworzyć domyślnych (pustych) sprajtów ... Poza tym potrzebuje bardzo dokładnego zaznaczania dla obrazów o rozdzielczości 16x16, 32x32, 64x64, 128x128, a nie jestem pewien czy ten kod sprawdzi się w tym przypadku. Jutro spróbuję to ogarnąć, bo dziś już nie siedzę na komputerze. |
|
DejaVu |
» 2025-10-13 23:37:32 Kod jest w SFML 2.x, ponieważ nie mam SFML 3.x, a tak mogłem przetestować. Niemniej jednak problemem jest algorytmika, a nie biblioteka renderująca. |
|
DejaVu |
» 2025-10-14 00:22:12 #include <SFML/Graphics.hpp> #include <vector> #include <iostream>
bool isPointInPolygon( const sf::Vector2f & point, const std::vector < sf::Vector2f > & polygon ) { if( polygon.size() < 3 ) return false; bool inside = false; int j = polygon.size() - 1; const float epsilon = 1e-6f; for( int i = 0; i < polygon.size(); ++i ) { if( std::abs( polygon[ i ].y - point.y ) < epsilon && std::abs( polygon[ i ].x - point.x ) < epsilon ) { return true; } if((( polygon[ i ].y > point.y ) !=( polygon[ j ].y > point.y ) ) && ( point.x <( polygon[ j ].x - polygon[ i ].x ) *( point.y - polygon[ i ].y ) /( polygon[ j ].y - polygon[ i ].y ) + polygon[ i ].x + epsilon ) ) { inside = !inside; } j = i; } return inside; } sf::Image extractRegion( const sf::Texture & texture, const std::vector < sf::Vector2f > & polygon ) { sf::Vector2u size = texture.getSize(); sf::Image result; result.create( size.x, size.y, sf::Color::Transparent ); sf::Image textureImage = texture.copyToImage(); const sf::Uint8 * pixels = textureImage.getPixelsPtr(); for( unsigned int y = 0; y < size.y; ++y ) { for( unsigned int x = 0; x < size.x; ++x ) { sf::Vector2f pixelCenter( x + 0.5f, y + 0.5f ); if( isPointInPolygon( pixelCenter, polygon ) ) { size_t index =( y * size.x + x ) * 4; sf::Color color( pixels[ index ], pixels[ index + 1 ], pixels[ index + 2 ], pixels[ index + 3 ] ); result.setPixel( x, y, color ); } } } return result; }
void drawLasso( const std::vector < sf::Vector2f > & points, bool closed, const sf::Color & color, sf::RenderWindow & window, float zoomFactor ) { if( points.size() < 2 ) return; sf::VertexArray lines( sf::LinesStrip, points.size() +( closed ? 1 : 0 ) ); for( size_t i = 0; i < points.size(); ++i ) { sf::Vector2f scaledPoint = points[ i ] * zoomFactor; lines[ i ].position = scaledPoint; lines[ i ].color = color; } if( closed && points.size() > 2 ) { lines[ points.size() ].position = points[ 0 ] * zoomFactor; lines[ points.size() ].color = color; } window.draw( lines ); }
int main() { sf::RenderWindow window( sf::VideoMode( 1800, 1200 ), "SFML Lasso Selection - Pixel-Perfect for Small Images" ); sf::Texture texture; if( !texture.loadFromFile( "D:/image.jpg" ) ) { std::cerr << "Error: Could not load image.jpg" << std::endl; return - 1; } sf::Sprite sprite; sprite.setTexture( texture ); sprite.setPosition( 0, 0 ); sf::Image selectedImage; sf::Texture selectedTexture; sf::Sprite selectedSprite; selectedSprite.setPosition( 650, 10 ); const float zoomFactor = 4.0f; sprite.setScale( zoomFactor, zoomFactor ); selectedSprite.setScale( zoomFactor, zoomFactor ); std::vector < sf::Vector2f > lassoPoints; std::vector < sf::Vector2f > lastLassoPoints; bool isDrawing = false; bool selectionDone = false; while( window.isOpen() ) { sf::Event event; while( window.pollEvent( event ) ) { if( event.type == sf::Event::Closed ) { window.close(); } if( event.type == sf::Event::MouseButtonPressed ) { if( event.mouseButton.button == sf::Mouse::Left ) { sf::Vector2f mousePos( event.mouseButton.x, event.mouseButton.y ); mousePos /= zoomFactor; lassoPoints.clear(); lassoPoints.push_back( mousePos ); isDrawing = true; selectionDone = false; } } if( event.type == sf::Event::MouseButtonReleased ) { if( event.mouseButton.button == sf::Mouse::Left ) { isDrawing = false; if( lassoPoints.size() > 2 ) { lastLassoPoints = lassoPoints; selectedImage = extractRegion( texture, lassoPoints ); selectedTexture.loadFromImage( selectedImage ); selectedSprite.setTexture( selectedTexture ); selectionDone = true; } } } if( event.type == sf::Event::MouseMoved && isDrawing ) { sf::Vector2f mousePos( event.mouseMove.x, event.mouseMove.y ); mousePos /= zoomFactor; lassoPoints.push_back( mousePos ); } } window.clear(); window.draw( sprite ); if( isDrawing && lassoPoints.size() > 1 ) { drawLasso( lassoPoints, false, sf::Color::Yellow, window, zoomFactor ); } if( !lastLassoPoints.empty() ) { drawLasso( lastLassoPoints, true, sf::Color::Green, window, zoomFactor ); } if( selectionDone && selectedImage.getSize().x > 0 && selectedImage.getSize().y > 0 ) { window.draw( selectedSprite ); } window.display(); } return 0; }
Tu masz lepiej działającą wersję - z zoomem o jakim piszesz i poprawionym offsetem kopiowania. |
|
tBane Temat założony przez niniejszego użytkownika |
» 2025-10-14 12:46:48 Z tego kodu wykorzystam chyba tylko funckję isPointInPolygon, ponieważ mój kod jest trochę bardziej zaawansowany tzn obsługuje różny rozmiar zaznaczenia oraz jego przesunięcie. Funkcję tę wyskorzystam do generowania maski zaznaczenia. |
|
tBane Temat założony przez niniejszego użytkownika |
» 2025-10-14 14:33:06 Zrobione :-) i działa! :D  bool Lasso::pointOnSegment( sf::Vector2i p, sf::Vector2i a, sf::Vector2i b ) { int cross = 1LL *( b.x - a.x ) *( p.y - a.y ) - 1LL *( b.y - a.y ) *( p.x - a.x ); if( cross != 0 ) return false; int minx = std::min( a.x, b.x ); int maxx = std::max( a.x, b.x ); int miny = std::min( a.y, b.y ); int maxy = std::max( a.y, b.y ); return( p.x >= minx && p.x <= maxx && p.y >= miny && p.y <= maxy ); }
bool Lasso::isPointInPolygon( sf::Vector2i p, std::vector < sf::Vector2i > & poly ) { size_t n = poly.size(); if( n < 3 ) return false; bool inside = false; for( size_t i = 0, j = n - 1; i < n; j = i++ ) { sf::Vector2i & a = poly[ j ]; sf::Vector2i & b = poly[ i ]; if( pointOnSegment( p, a, b ) ) return true; bool crossesY =(( a.y > p.y ) !=( b.y > p.y ) ); if( !crossesY ) continue; int dy = b.y - a.y; int lhs =( p.x - a.x ) * dy; int rhs =( b.x - a.x ) *( p.y - a.y ); bool hit =( dy > 0 ) ?( lhs < rhs ) :( lhs > rhs ); if( hit ) inside = !inside; } return inside; }
sf::Image * Lasso::generateMask() { if( !_image ) return nullptr; if( _image->getSize().x == 0 || _image->getSize().y == 0 ) return nullptr; sf::Vector2u size = _image->getSize(); sf::Image * maskImage = new sf::Image(); maskImage->resize( size, sf::Color::Transparent ); for( unsigned int y = 0; y < size.y; ++y ) { for( unsigned int x = 0; x < size.x; ++x ) { if( isPointInPolygon( sf::Vector2i( x, y ), _points ) ) { maskImage->setPixel( sf::Vector2u( x, y ), sf::Color::White ); } } } return maskImage; }
|
|
| 1 2 3 4 « 5 » 6 |